Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/373.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 用摩卡对react组件进行单元测试_Javascript_Unit Testing_Reactjs_Redux - Fatal编程技术网

Javascript 用摩卡对react组件进行单元测试

Javascript 用摩卡对react组件进行单元测试,javascript,unit-testing,reactjs,redux,Javascript,Unit Testing,Reactjs,Redux,我正在研究生态系统的TodoMVC示例。我已经完成了示例的工作代码,现在正在为应用程序的每个元素创建测试 对于Action和Reducer来说,测试非常简单,但是对于组件来说,编写测试更具挑战性 我的通用组件体系结构如下所示: Home.js \-App.js \-TodoList.js \-TodoItem.js \-Todo

我正在研究生态系统的TodoMVC示例。我已经完成了示例的工作代码,现在正在为应用程序的每个元素创建测试

对于Action和Reducer来说,测试非常简单,但是对于组件来说,编写测试更具挑战性

我的通用组件体系结构如下所示:

Home.js
      \-App.js
              \-TodoList.js
                          \-TodoItem.js
                                       \-TodoInput.js
为TodoInput.js编写单元测试相对简单:

TodoInput.js:

handleChange(e) {
    this.setState({ text: e.target.value });
  }

...

  render() {

    return (
      <input type="text" autoFocus='true'
            className={classnames({
              edit: this.props.editing,
              'new-todo': this.props.newTodo
             })}
            value={this.state.text}
            placeholder={this.props.placeholder}
            onKeyDown={this.handleKeyDown.bind(this)}
            onBlur={this.handleBlur.bind(this)}
            onChange={this.handleChange.bind(this)}>
      </input>
    );
  }
我有点困惑于如何编写一个测试,例如,它将验证双击组件是否已成功地将状态设置为
editing:true

通常,我将测试分为两部分,“呈现”和“事件”,即TodoItem-test.js:

import React, { addons } from 'react/addons';
import _ from 'lodash';
import expect from 'expect';
const { TestUtils } = addons;

import TodoItem from '../TodoItem';

describe('TodoItem', () => {

  const mockedTodo = {
    text: 'abc123',
    complete: false
  };

describe('rendering', () => {
    let component;

    before(() => {
      component = TestUtils.renderIntoDocument(
        <TodoItem
          todo={mockedTodo}
          editTodo={_.noop}
          markTodoAsComplete={_.noop}
          deleteTodo={_.noop}
        />
      );
    });

    afterEach(() => {
      React.unmountComponentAtNode(React.findDOMNode(component));
    });

    it('should render the element', () => {
      const liComponent = TestUtils.findRenderedDOMComponentWithTag(component, 'li');

      expect(liComponent).toExist();
    });

    it('should render text in label', () => {
      const labelComponent = TestUtils.findRenderedDOMComponentWithTag(component, 'label');

      expect(labelComponent).toExist();
      expect(React.findDOMNode(labelComponent).textContent).toEqual('abc123');
    });
  });

 describe('events', () => {
  ...

});
如何进行测试以确保已设置编辑标志?
liComponent.props.editing
返回
未定义。

其次,使用一个
上下文(“如果组件处于编辑模式”)
进行测试,以确保以下内容已正确呈现:

  <li className={classnames({
    completed: todo.complete,
    editing: this.state.editing
  })}>
      <TodoInput text={todo.text}
                   editing={this.state.editing}
                   onSave={(text) => this.handleSave(todo.id, text)} />
  </li>
  • this.handleSave(todo.id,text)}/>

  • 我也不确定如何严格测试它。

    liComponent.props
    未定义,因为liComponent是DOM元素,而不是react组件。之所以如此,是因为您使用
    findRenderedomComponentWithTag
    获取它。实际上,您已经可以访问要测试的React组件

    it('should render the element', () => {
        const liComponent = TestUtils.findRenderedDOMComponentWithTag(component, 'li');
    
        // `component` is from your `before` function
        expect(component.state.editing).toBe(false);
    
        // Make sure you're simulating on a DOM element
        TestUtils.Simulate.doubleClick(liComponent);
    
        expect(component.state.editing).toBe(true);
    });
    

    然后,您可以使用
    scryRenderedComponentsWithType
    来检查是否呈现了
    TodoInput

    这让我更接近了--我可以访问component.state--但是双击事件并没有触发编辑为真。实际上,这看起来可能是因为您在模拟双击<代码>反应。在DOM节点上调用findDOMNode可能不会返回任何结果。
    describe('events', () => {
        let component;
        let deleteTodoCallback = sinon.stub();
    
        beforeEach(() => {
          component = TestUtils.renderIntoDocument(
            <TodoItem
              todo={mockedTodo}
              editTodo={_.noop}
              markTodoAsComplete={_.noop}
              deleteTodo={deleteTodoCallback}
            />
          );
        });
    
        afterEach(() => {
          React.unmountComponentAtNode(React.findDOMNode(component));
        });
    
        it(`should change the editing state to be true if a user double-clicks
              on the todo`, () => {
    
            const liComponent = TestUtils.findRenderedDOMComponentWithTag(component, 'li');
    
            // expect the editing flag to be false
    
            TestUtils.Simulate.doubleClick(React.findDOMNode(liComponent));
    
            // expect the editing flag to be true
    
        });
      });
    
      <li className={classnames({
        completed: todo.complete,
        editing: this.state.editing
      })}>
          <TodoInput text={todo.text}
                       editing={this.state.editing}
                       onSave={(text) => this.handleSave(todo.id, text)} />
      </li>
    
    it('should render the element', () => {
        const liComponent = TestUtils.findRenderedDOMComponentWithTag(component, 'li');
    
        // `component` is from your `before` function
        expect(component.state.editing).toBe(false);
    
        // Make sure you're simulating on a DOM element
        TestUtils.Simulate.doubleClick(liComponent);
    
        expect(component.state.editing).toBe(true);
    });