如何使用重构组合来测试反应组件

时间:2017-06-20 18:07:39

标签: javascript reactjs recompose

最近开始使用重构(https://github.com/acdlite/recompose

我想知道我应该如何处理单元测试组件,这些组件包含了一些重构的重组提供?我喜欢用功能方法替换整个类组件,但在单元测试方面却完全不正确。

例如,使用给定的列表组件

export const ListItem = toClass(pure(({ text }) => <li>{text}</li>));
const renderItems = R.map(t => <ListItem key={t} text={t} />);

export const ListComponent = toClass(({ todos, name, updateName, addTodo }) =>
  <div>
    <input onChange={updateName} value={name} />
    <button onClick={() => addTodo(name)}>add todo</button>
    <ul>
      {renderItems(todos)}
    </ul>
  </div>
);

...

const List = compose(
  withReducer("state", "dispatch", listReducer, props => ({
    ...initialState,
    ...props
  })),
  withHandlers({
    updateName: ({ dispatch }) => e =>
      dispatch({ type: "UPDATE_NAME", payload: e.target.value }),
    addTodo: ({ dispatch, name }) => name =>
      dispatch({ type: "ADD_TODO", payload: name })
  }),
  flattenProp("state")
)(ListComponent);

export default List;

如何用给定的道具测试孩子的长度?我尝试过类似的东西,但它没有用。

it("renders todos list", () => {
    const component = shallow(<List todos={["todo1", "todo2", "todo3"]} />);
    expect(component.instance().children).toHaveLength(3);
  });

2 个答案:

答案 0 :(得分:4)

请勿使用mount代替shallow。请将.dive()shallow一起使用。

Mount也会渲染所有子元素,这对单元测试不利。

答案 1 :(得分:1)

你绝对可以通过重构来测试你的功能。您只是以不可测试的方式使用逻辑。让我举一个例子来说明我将如何测试updateName

我会创建一个名为updateName

的函数
export const updateName = props => event =>
  props.dispatch({ type: "UPDATE_NAME", payload: event.target.value })

根据您使用函数的方式,重要的是要了解这是一个集成测试。不是单元测试。我们正在测试是否使用正确的参数调用了调度函数。就这些。所以我们的测试文件可能如下所示

const mockDispatch =  jest.fn();
const props = {dispatch: mockDispatch}
const event = {
 target: {
  value:'john'
 }
}
updateName(props, event);
expect(mockDispatch.mock.calls).toEqual([{ type: "UPDATE_NAME", payload: 'john' }])

Ta da!

并在您的容器中,您将使用它:

List = compose(
 withHandlers({
  updateName
 })
)