5

我使用 Jest 来测试我的 React 组件。但是,我不知道(或没有看到任何东西)如何测试将方法(作为道具)传递给子组件的组件。例如,我有:Form, MemberList, Member, FormButton. 代码中与此类似的东西:

形式:

<MemberList members={this.state.members} remove={this.remove} add={this.add} />
<FormButton data={this.state.members} />

会员名单:

<span onClick={this.add}> <!-- add button --> </span>
{this.props.members.map(function(member, index) {
  <Member key={index} data={member} remove={this.props.remove} />
})}

成员:

// some input like name and so, and a remove itself button.

表单按钮:

var submit = function() {
    this.setState({ loading: true });

     // xhr
}
<button type="button" onClick={submit} disabled={this.state.loading}>Submit</button>

我的思维方式是否正确?补充一下,有没有实际的例子?

*在尝试 React 和 Jest 之前我从未测试过。

4

1 回答 1

5

解决方案是将模拟函数直接传递给子组件并对其进行测试。任何涉及多个“子组件”的东西通常都不是真正的单元测试,因为您正在测试多个功能单元。

所以我会创建MemberList-test.js

describe('MemberList', function () {
  it('calls the add handler when add is clicked', function () {
    var Component = TestUtils.renderIntoDocument(
      <MemberList add={ jest.genMockFn() } />
      );

    const btn = TestUtils.findRenderedDOMComponentWithTag(Component, 'span')

    TestUtils.Simulate.change(btn);

    expect(Component.add.mock.calls.length).toBe(1)

  })
})

然后,与其尝试在您应该创建的同一测试中直接测试您的成员组件Member-test.js

describe('Member', function () {
  it('calls the add handler when add is clicked', function () {
    var Component = TestUtils.renderIntoDocument(
      <Member remove={ jest.genMockFn() } />
      );

    const btn = TestUtils.findRenderedDOMComponentWithTag(Component,
      'HOWEVER YOU FIND YOUR REMOVE BUTTON')

    TestUtils.Simulate.change(btn);

    expect(Component.remove.mock.calls.length).toBe(1)

  })
})

现在您缺少的断言是传递到成员列表的删除处理程序正确地传递给成员组件。所以让我们添加另一个测试MemberList-test.js

it('passes correct information to the children', function () {
  var MemberMock = require('../Member')
  var removeFn = jest.genMockFn();

  var testMember = {WHATEVER YOUR MEMBER OBJECT LOOKS LIKE}

  var Component = TestUtils.renderIntoDocument(
    <MemberList members={ [testMember] }
      remove={ removeFn } />
    );

  // We expect the member component to be instantiated 1 time and
  // passed the remove function we defined
  // as well as a key and the data
  expect(MemberMock.mock.calls).toEqual([[{key: 0, data: testMember,
    remove: removeFn}]])

})

然后,您只需对表单组件执行相同的模式。模拟成员列表和按钮并分别测试它们并看到正确的处理程序和数据被传递下来。

希望这是有道理的,如果不只是回复,也许我可以通过 Skype 或其他方式引导您完成它。

于 2014-12-07T22:03:32.450 回答