Javascript 如何在Jasmine/React中使用范围输入测试`onChange`事件

Javascript 如何在Jasmine/React中使用范围输入测试`onChange`事件,javascript,jasmine,phantomjs,reactjs,Javascript,Jasmine,Phantomjs,Reactjs,我在Jasmine测试中使用onChange和React时遇到问题。我看到的特别问题是范围输入。假设在onChange事件之后,React组件中的类名发生了更改。在Jasmine中,我无法在测试中手动触发onChange,以便随后断言DOM更改 到目前为止,我所尝试的一切都不起作用——无论是使用React.addons.TestUtils,还是仅仅在相关节点上执行一个简单的$node.trigger“change”。我无法使onChange在React节点上启动。是否有人认为这个示例代码有任何错

我在Jasmine测试中使用onChange和React时遇到问题。我看到的特别问题是范围输入。假设在onChange事件之后,React组件中的类名发生了更改。在Jasmine中,我无法在测试中手动触发onChange,以便随后断言DOM更改

到目前为止,我所尝试的一切都不起作用——无论是使用React.addons.TestUtils,还是仅仅在相关节点上执行一个简单的$node.trigger“change”。我无法使onChange在React节点上启动。是否有人认为这个示例代码有任何错误,或者我遗漏了什么

例如,下面是Jasmine代码示例:

// assuming I already have full access to node and its in the DOM
var node = React.findDOMNode(this.refs.input);

// updating input `value` manually
node.value = 10;

// simulate change to `input` so that `onChange` will fire
React.addons.TestUtils.Simulate.change(node);
// or React.addons.TestUtils.Simulate.change(node, { target: { value: 10 } });

// assert that sample `className` is changed for example, this could be anything - just a simple assertion that something in the DOM changed as expected
expect(node.className).not.toBe('hidden');
我永远无法通过上面的期望-DOM中没有任何东西能够检测到相关节点上的值更改

这里还有一个代码笔来说明这个问题:


谢谢大家的帮助

当我使用TestUtils时,它看起来工作正常。就我的一生而言,我不知道为什么我以前不能让它完全工作。但这里有一个解决方案,以防其他人需要它:

反应试验 /**@jsx.DOM*/ var sampleInput=React.createClass{ getInitialState:函数{ 返回{ 输入值:2 } }, updateValue:function{ //更新文本值 this.setState{inputVal:e.currentTarget.valueAsNumber}; }, 渲染:函数{ 回来 } }; //茉莉花 描述“组件”的功能{ var TestUtils=React.addons.TestUtils; 变量输入; 描述“带输入范围”功能{ 它'更新其值'onChange`',函数{ inputInstance=TestUtils.renderIntoDocument React.createElementsampleInput,{sample:true} ; //健康检查 expectinputinance.props.sample.toBetrue; var input=React.findDOMNodeinputInstance.querySelector'input'; input.value=10; TestUtils.Simulate.changeinput; expectinput.valueAsNumber.toBe10; expectinputInstance.state.inputVal.toBe10; }; }; };
当我使用TestUtils时,它看起来工作正常。就我的一生而言,我不知道为什么我以前不能让它完全工作。但这里有一个解决方案,以防其他人需要它:

反应试验 /**@jsx.DOM*/ var sampleInput=React.createClass{ getInitialState:函数{ 返回{ 输入值:2 } }, updateValue:function{ //更新文本值 this.setState{inputVal:e.currentTarget.valueAsNumber}; }, 渲染:函数{ 回来 } }; //茉莉花 描述“组件”的功能{ var TestUtils=React.addons.TestUtils; 变量输入; 描述“带输入范围”功能{ 它'更新其值'onChange`',函数{ inputInstance=TestUtils.renderIntoDocument React.createElementsampleInput,{sample:true} ; //健康检查 expectinputinance.props.sample.toBetrue; var input=React.findDOMNodeinputInstance.querySelector'input'; input.value=10; TestUtils.Simulate.changeinput; expectinput.valueAsNumber.toBe10; expectinputInstance.state.inputVal.toBe10; }; }; };
在你自己的答案上加上我的2美分

更好的选择是在jasmine上设置一个spy函数,并检查它是否已被调用:

describe('A component', () => {
  describe('when it renders', () => {
    it('should trigger the onChange function', () => {
      const callback = jasmine.createSpy('changed');

      const sut = TestUtils.renderIntoDocument(
        <MyReactComponent onChange={callback}>BlaBlaBla</MyReactComponent>
      );
      const domNode = ReactDOM.findDOMNode(sut);

      const input = domNode.querySelector('input');

      TestUtils.Simulate.change(input);

      expect(callback).toHaveBeenCalled();
    });
  });
});

在你自己的答案上加上我的2美分

更好的选择是在jasmine上设置一个spy函数,并检查它是否已被调用:

describe('A component', () => {
  describe('when it renders', () => {
    it('should trigger the onChange function', () => {
      const callback = jasmine.createSpy('changed');

      const sut = TestUtils.renderIntoDocument(
        <MyReactComponent onChange={callback}>BlaBlaBla</MyReactComponent>
      );
      const domNode = ReactDOM.findDOMNode(sut);

      const input = domNode.querySelector('input');

      TestUtils.Simulate.change(input);

      expect(callback).toHaveBeenCalled();
    });
  });
});

同样值得一提的是,通过将值传递到`TestUtils.Simulate.changeinput;`像`TestUtils.Simulate.changeinput,{target:{value:10};`,所以这看起来像是核心问题。当您调用TestUtils.Simulate.changeinput,{target:{value:10};,您基本上是在传递{target:{value:10}}作为updateValue的e对象。因此,如果您要修改updateValue,使其查找e.target.value而不是e.currentTarget.valueAsNumber,它将能够读取您传递的值。因此,通过将值传递到`TestUtils.Simulate.changeinput;`like`TestUtils.Simulate.c,我永远无法让测试通过hangeinput,{target:{value:10};`,这看起来像是核心问题。当您调用TestUtils.Simulate.changeinput,{target:{value:10};,您基本上是在传递{target:{value:10}}作为updateValue的e对象。因此,如果要修改updateValue使其查找e.target.value而不是e.currentTarget.valueAsNumber,它将能够读取您传递的值