React的TestUtils.Simulate.keyDown无法正常工作

9

我有很多组件在我的应用程序中响应不同的按键,到目前为止,我使用 TestUtils.Simulate.keyDown 的所有测试都没有起作用。看起来 keyDown 就是根本不工作。

这是我正在尝试测试的组件:

description.js

var React = require('react/addons');

var Description = React.createClass({
    render : function () {
        return (
            <div className="description">
                <input type="text" ref="input"/>
            </div>
        )
    }
});

module.exports = Description;

这里有一个简单的测试不通过:

description-test.js

var React = require('react/addons');
var TestUtils = React.addons.TestUtils;
var expect = require('expect');
var Description = require('../description');

describe('Description', function () {
    it('updates input value on key press', function () {
        var description = TestUtils.renderIntoDocument(<Description/>);
        var input = React.findDOMNode(description.refs.input);
        expect(input.value).toEqual(''); //This passes
        TestUtils.Simulate.keyDown(input, {key : "a"});
        expect(input.value).toEqual('a'); //This fails
    });
});

我有多个测试依赖于 TestUtils.Simulate.keyDown。这些测试尝试按下多种不同的键(其中 Enter 键最突出),但是没有一个有效。我尝试使用 keyPresskeyUp,但不知道这些函数是否存在(向那些令人惊讶的不完整文档致敬)。
我是否只是在错误地使用该函数?还是其他地方出了问题?
如果我使用 npm 中的 karma-cli 运行我的测试,会有所不同。
3个回答

10

我最终解决了这个问题。

TestUtils.Simulate.keyDown(input, {key : "a"});

这行代码会向正确的DOM节点发送一个事件,但实际上事件数据不包含keyCode,而代码却在寻找它。为什么官方文档明确建议使用key我无从得知。

要使其功能正常,需要进行以下修改:

TestUtils.Simulate.keyDown(input, {keyCode : 65});

我希望这能帮助到其他遇到类似问题的人。


3

TestUtils.Simulate 仅模拟目标元素上的事件,而不实际更改值。因此,如果您在 input 上有一个 onKeyDown 处理程序,则使用 TestUtils 模拟 keyDown 将让您查看该处理程序是否正常工作。

要更改 input 的值,您可以尝试直接更改它:this.refs.input.value = 'a',或者如果您想测试一个 onChange 处理程序,则模拟一个更改事件:

TestUtils.Simulate.change(input, { target: { value: 'a' } })

感谢您的回复。实际上,这个组件确实有一个 onKeyDown 处理程序,但为了简单起见,我从原始问题中剥离了它。该处理程序寻找用户按下 Enter 和 Backspace 键,虽然该组件在页面上正常运行,但是对于此处理程序的测试却没有正常运行。 - Michael Parker
好的@MichaelParker,无论如何,在模拟“keyDown”之后,“input.value”不等于“'a'”是正确的。如果您无法有效地使用“TestUtils”模拟输入回车/退格键,则可能需要更改上面的示例代码/测试,然后我们可以从那里开始。 - glortho
我其实找到了问题的答案,可以看一下我的回答。不过还是很感谢你的回复 :) - Michael Parker

0
仅供记录,我遇到了一个非常类似的问题,来自于一个SearchInput组件,当按下回车键时发送输入的文本。我进行了一些如下的测试:
describe('SearchInput functionality,', () => {
  let mockData, component, input;

  beforeAll(() => {
    mockData = {
      searchCriteria: "something",
      emptyString: "       ",
      submitHandler: function(filter) {
        // storing filter param in mockData, it means SearchInput called handler successfully
        mockData.filter = filter;
      }
    };

    spyOn(mockData, 'submitHandler').and.callThrough();

    component = ReactTestUtils.renderIntoDocument(
      <SearchInput placeholder="Search..." onSubmit={mockData.submitHandler}/>
    );
    input = ReactTestUtils.findRenderedDOMComponentWithTag(component, 'input');
  });

  it('user writes a search criteria and hits enter', () => {
    input.value = mockData.searchCriteria;
    ReactTestUtils.Simulate.change(input);
    ReactTestUtils.Simulate.keyDown(input, {key: "Enter", keyCode: 13, which: 13});

    expect(mockData.filter).toEqual(mockData.searchCriteria);
    expect(mockData.submitHandler).toHaveBeenCalled();
    expect(mockData.submitHandler).toHaveBeenCalledTimes(1);
  });
});

但是它没有起作用。

但经过一些研究,我将 keyDown 改为 keyPress,然后一切都完美地运行了。原因是回车键实际上从未被按下,因此输入值从未被发送,所有的断言都失败了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接