在React中,如何测试组件内的render方法

时间:2017-10-31 15:34:24

标签: javascript reactjs unit-testing enzyme jest

我有一个组件,它有一个用于呈现表的render方法。现在我需要在react中实现一个单元测试来测试该方法(renderTaskAssign())并查看表是否成功呈现。谁能告诉我怎么做?这是关于课程的详细信息,我希望我可以编写测试。

class TaskAssign extends Component {
  constructor(props) {
    super(props);
    this.renderTaskAssign = this.renderTaskAssign.bind(this);
  }

  renderTaskAssign() {
    if (this.props.data_loading) {
      return (
        <div className="dataloader">
        <ClipLoader
          color={types.LOADING_DATA_COLOR}
          loading={this.props.data_loading}
        />
        </div>);
    } else {
      if (this.props.current_tasks !== '') {
        const item_list = this.props.current_tasks.map((key, index) => {
          return (
              <TableRow key={index}>
              <TableRowColumn>{this.props.current_tasks[index]['pos']}</TableRowColumn>
              <TableRowColumn>{this.props.current_tasks[index]['name']}</TableRowColumn>
              <TableRowColumn>{this.props.current_tasks[index]['completion']}</TableRowColumn>
              <TableRowColumn>{this.props.current_tasks[index]['current_task']}</TableRowColumn>
              <TableRowColumn>{this.props.current_tasks[index]['percent_complete']}</TableRowColumn>
              <TableRowColumn>{this.props.current_tasks[index]['status']}</TableRowColumn>
              <TableRowColumn>Do nothing</TableRowColumn>
              </TableRow>
          );
          })
        return (
          <Table multiSelectable>
          <TableHeader>
            <TableRow>
            <TableHeaderColumn>Pos</TableHeaderColumn>
            <TableHeaderColumn>Installer</TableHeaderColumn>
            <TableHeaderColumn>Work Progress</TableHeaderColumn>
            <TableHeaderColumn>Current Task</TableHeaderColumn>
            <TableHeaderColumn>% Completion</TableHeaderColumn>
            <TableHeaderColumn>Status</TableHeaderColumn>
            <TableHeaderColumn>Add.Info</TableHeaderColumn>
            </TableRow>
          </TableHeader>
            <TableBody>
            {item_list}
            </TableBody>
            </Table>
          );
      }
    }
  }

  render() {
    return (
      <div>
        {this.renderTaskAssign()}
      </div>
    );
  }
}

const mapStateToProps=({ task })=> {
  const { current_tasks, error, data_loading } = task;
  return { current_tasks, error, data_loading };
};

export default connect(mapStateToProps)(TaskAssign);

我尝试用酶来测试组件,这是我写的测试代码。我不知道如何在我的案例中测试表

it("test renderTaskAssign method", () => {
    const renderer = new ShallowRenderer();
    renderer.render(<Provider store={store}>
    <TaskAssign />
    </Provider>);
    const result = renderer.getRenderOutput();
    const taskComponent = new result.type.WrappedComponent();
    taskComponent.props = {
      current_tasks: [
        0: {
          completion: 0.76,
          current_task: 'REASSEMBLE DOORS',
          name: 'A. Smith',
          percent_complete: 0.5,
          pos: 'A1',
          status: 'Good'
        },
        1: {
          completion: 0.66,
          current_task: 'ASEASSEMBLE DOORS',
          name: 'B. Smith',
          percent_complete: 0.7,
          pos: 'B1',
          status: 'Soso'
        }
      ]
    };
    taskComponent.renderTaskAssign()
    console.log(taskComponent.renderTaskAssign().type);
  }
);

3 个答案:

答案 0 :(得分:1)

实际上,您应该测试组件的行为,而不是其实现。从组件的外部,您不应该关心它是否具有renderTaskAssign或此函数的功能,而只关心组件执行/呈现的内容。

您想要做的是使用特定的道具测试您的组件,而无需等待Redux连接将它们注入您的组件。我建议如下,您只测试您的组件,而不是您的商店:

class TaskAssign extends Component {
  constructor(props) {
    super(props);
    this.renderTaskAssign = this.renderTaskAssign.bind(this);
  }

  renderTaskAssign() {
      // some render code
  }

render() {
    return (
      <div>
        {this.renderTaskAssign()}
      </div>
    );
  }
}

const mapStateToProps=({ task })=&gt; {
  const { current_tasks, error, data_loading } = task;
  return { current_tasks, error, data_loading };
};

export default connect(mapStateToProps)(TaskAssign);

export const TaskAssign // <- This enables you to test your component, without the mapStateToProps connection. 

然后:

import { TaskAssign } from './'; // <-- Import the 'unconnected' version

it("test renderTaskAssign method", () => {
    const renderer = new ShallowRenderer();
    renderer.render( // <- Directly inject your props, not need for an entire store
    <TaskAssign current_tasks={[
        0: {
          completion: 0.76,
          current_task: 'REASSEMBLE DOORS',
          name: 'A. Smith',
          percent_complete: 0.5,
          pos: 'A1',
          status: 'Good'
        },
        1: {
          completion: 0.66,
          current_task: 'ASEASSEMBLE DOORS',
          name: 'B. Smith',
          percent_complete: 0.7,
          pos: 'B1',
          status: 'Soso'
        }
      ]} />
    );
    const result = renderer.getRenderOutput();

    // Test whatever you want : 
    expect(wrapper.is(Table)).toEqual(true);
    expect(wrapper.find(TableRowColumn).length).toEqual(7);
  }
);

现在,从那里(并且完全超出范围:-)):

  • 我不明白你的renderTaskAssign功能
  • 的效用是什么
  • 建议尽可能使用功能组件(无生命周期)。
  • 您可以将地图替换为其他组件
  • 您可以使用babel-plugin-jsx-control-statements来简化您的JSX

所以,我实际上会写这样的组件:

const TaskAssign = ({ current_tasks, data_loading }) => (
  <div>
    <Choose>
      <When condition={data_loading} />
        <div className="dataloader">
          <ClipLoader
            color={types.LOADING_DATA_COLOR}
            loading={data_loading}
          />
          </div>
      </When>
      <When condition={current_tasks !== ''}>
        <Table multiSelectable>
          <TableHeader>
            <TableRow>
            <TableHeaderColumn>Pos</TableHeaderColumn>
            <TableHeaderColumn>Installer</TableHeaderColumn>
            <TableHeaderColumn>Work Progress</TableHeaderColumn>
            <TableHeaderColumn>Current Task</TableHeaderColumn>
            <TableHeaderColumn>% Completion</TableHeaderColumn>
            <TableHeaderColumn>Status</TableHeaderColumn>
            <TableHeaderColumn>Add.Info</TableHeaderColumn>
            </TableRow>
          </TableHeader>
            <TableBody>
              <For each="task" of={current_tasks} >
                <SomeItemTableRowComponent task={task} />
              </For>
            </TableBody>
            </Table>
          </When>
        </Choose>
      </div>
    );

const mapStateToProps=({ task })=&gt; {
  const { current_tasks, error, data_loading } = task;
  return { current_tasks, error, data_loading };
};

export default connect(mapStateToProps)(TaskAssign);

export const TaskAssign

希望有所帮助

答案 1 :(得分:0)

基本上,使用 Enzyme ,您可以检查内部组件是否已呈现。例如:

it('should use Table', () => {
    const wrapper = shallow(
      <TaskAssign />
    );
    expect(wrapper.is(Table)).toBe(true);
  });

然后,您可以检查此组件是否包含另一个组件。例如:

it('should render multiple header columns', () => {
    const wrapper = mount(
      <TaskAssign />
    );
    expect(wrapper.find(TableRowColumn).length).toBe(7);
  });

答案 2 :(得分:0)