0

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

我想知道我应该如何处理包含一些 hocs 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);
  });

4

2 回答 2

4

不要使用mount代替shallow. 改用.dive()with shallow

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

于 2017-10-26T14:16:05.453 回答
1

你绝对可以用 recompose 来测试你的函数。您只是以不可测试的方式使用您的逻辑。让我举个例子说明我将如何测试 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' }])

达达!

在你的容器中你会这样使用它:

List = compose(
 withHandlers({
  updateName
 })
)
于 2018-04-23T01:57:46.347 回答