如何正确测试反应组件?

时间:2017-06-30 08:28:28

标签: unit-testing reactjs testing jestjs enzyme

最近我正在学习用开玩笑和酶来测试React,似乎很难理解单元测试是什么,我的代码

import React from "react";

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      value: ""
    };
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(e) {
    const value = e.target.value;
    this.setState({
      value
    });
  }
  render() {
    return <Nest value={this.state.value} handleChange={this.handleChange} />;
  }
}

export const Nest = props => {
  return <input value={props.value} onChange={props.handleChange} />;
};

export default App;

和我的测试

import React from "react";
import App, { Nest } from "./nest";

import { shallow, mount } from "enzyme";

it("should be goood", () => {
  const handleChange = jest.fn();
  const wrapper = mount(<App />);
  wrapper.find("input").simulate("change", { target: { value: "test" } });
  expect(handleChange).toHaveBeenCalledTimes(1);
});

IMO,被模拟的handleClick将拦截handleClick上的App

如果这是完全错误的,那么使用mock fn和测试handleClick的正确方法是什么。

另一个:我经常搜索,阅读类似的情况,看起来像是contra-Unit Test
可能我应该分别测试这两个组件,我可以测试两个组件, 测试 <Nest value={value} handleChange={handleChange} />
通过手动传递道具,然后通过模拟handleChange来调用change 它通过了测试 但是我怎样才能测试两者之间的联系呢? 我读了

  

一些工作是React Team的工作   ...

我不知道在这种情况下我必须测试哪些部分,以及哪些部分react已经测试过,并且不需要我进行测试。那令人困惑。

2 个答案:

答案 0 :(得分:0)

首先应该采用隔离测试Nest组件的路径,将模拟的handleChange作为道具传递,以验证输入更改是否正在传播。

如果你想测试状态部分,那么你可以从酶中获取你的App类的instance并直接调用该方法:

it("should update the Nest value prop when change is received", () => {
  const wrapper = mount(<App />);
  const instance = wrapper.instance()
  instance.handleChange( { target: { value: "test" } })
  const nestComponent = wrapper.find("Nest").first()      
  expect(nestComponent).prop('value').toEqual('test');
});

这是一个非常基本的,几乎不需要测试一段代码,但是如果那就是你所追求的那样,它会让你的测试覆盖率提高。

例如,

Doc:http://airbnb.io/enzyme/docs/api/ReactWrapper/instance.html

答案 1 :(得分:0)

如果要测试连接。从我所看到的,嵌套组件是App组件内部的子组件。您可以测试<App />包含`。

describe('<App />', () => {
  it('should contain a nest component', () => {
    const wrapper = mount(<App />);
    expect(wrapper.find(<Nest />)).toHaveLength(1);
  });
});

第二,由于nest组件上的onChange事件更新了App组件中的状态,因此您还可以测试状态更改,因为它是您期望的行为。

it('should update state', () => {
  //find input and simulate change with say {value: 'new value'} and then
  expect(wrapper.state().value).toBe('newValue');
});

我希望这会有所帮助。