【问题标题】:unit testing using enzyme: Pass react props as event to wrapper使用酶进行单元测试:将反应道具作为事件传递给包装器
【发布时间】:2018-12-12 13:30:32
【问题描述】:

我的测试失败,因为我不知道在 onChange 值中声明什么,

describe("App", function() {
  const wrapper = shallow(<App />);

  it("should have an input", function() {
    expect(
      wrapper.contains(<input type="text" onChange={null} />)
    ).toBeTruthy();
  });
});

我的组件中只有这个

<input type="text" onChange={this.changeInput} />

【问题讨论】:

  • 你可以试试onChange={() => jest.fn()}
  • 真正简单的expect(wrapper).toMatchSnapshot() 怎么样?它检查了更多属性/组件,您可以在 expect(wrapper.find(...)).to 中硬编码
  • @skyboyer 我试图说服自己,即使这是有道理的,测试 ui 对我来说很奇怪,因为一旦 ui 在那里,就意味着它会在那里,我可以测试功能但测试 ui 存在似乎工作太多了。
  • 这就是为什么你一定要看看testing with snapshots :)

标签: reactjs jestjs enzyme


【解决方案1】:

should have an input 测试根本不应该涉及onChange。可以像the reference 建议的那样进行测试:

expect(wrapper.find('input[type="text"]')).to.have.lengthOf(1);

onChange 可以在另一个测试中进行测试,类似于this question 中显示的方式。

【讨论】:

  • 如果输入被一个更高阶的组件包裹,比如&lt;MyInput /&gt;
  • 然后你断言有wrapper.find(MyInput) 并测试MyInput 在另一个测试中是如何工作的。这是正确的单元测试策略。
  • 如果 MyInput 只是一个无状态的组件,我们还需要测试它们吗?
  • 自动化测试旨在用机器工作代替人眼。编写单元测试应该是乏味的。当您花费数小时试图找出测试失败的原因并对其进行调试时,它可以大规模地节省时间 - 这就是这变得非常乏味的时候。单元测试越详细,故障排除就越有效。我建议阅读更多有关单元测试以及它们与其他类型测试的区别的信息。
  • @Hoknimo 然后经常固定测试以通过。修复应该是绿色的红色测试比修复应该是红色的绿色测试要容易得多。您可以在单元测试和 e2e 测试之间取得平衡,并使单元测试对特定项目的限制更少或更多,但这取决于项目。
【解决方案2】:

我在这里要做的是首先检查输入元素是否存在:

it('verifies that an input element is rendered', () => {
  expect(wrapper.exists('input')).toBeTruthy();
});

然后,通过验证,单独验证onChange 函数是否存在。我不支持在单个it 语句中进行多次验证,因为如果任何expect 语句触发失败,那么下面的所有expect 语句都不会执行。所以我会使用一个单独的it,如下所示:

it('verifies that an onChange function is set`, () => {
  expect(typeof wrapper.find('input').prop('onChange')).toBe('function');
});

另一种选择是为您的 onChange 属性设置一个模拟函数并验证它是否被正确调用,如下所示:

const testOnChange = jest.fn();
const wrapper = mount(<App onChange={testOnChange} />);

it('verifies that the onChange function is invoked', () => {
  wrapper.find('input').prop('onChange')();
  expect(testOnChange.mock.calls).toHaveLength(1);
});

【讨论】:

  • 我明白了。很好,你把它分开了,但是这个测试verifies that an "onChange" function is set 需要吗?我通常只测试它是否被调用,为什么这是测试 100% 工作的重点?
  • 这只是您可以验证onChange 确实已被传递的一种方式的示例。 OP 还可以测试它是使用模拟函数调用的。那是一个更好的选择。我已经更新了我的答案以包含它。
  • 有什么理由不使用 toHaveBeenCalled?
  • 没有。你可以使用任何一个。
  • 另一个问题,为什么不用stimulus('onChange')?
【解决方案3】:

你可以期待(wrapper.find('input').length).toBe(1)

不确定语法或函数名称,但它在那里 :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-27
    • 2017-09-24
    • 1970-01-01
    • 2016-04-28
    • 1970-01-01
    • 1970-01-01
    • 2019-03-04
    • 2017-01-31
    相关资源
    最近更新 更多