【问题标题】:How do I test that a thunk was passed to dispatch?如何测试一个 thunk 是否已通过调度?
【发布时间】:2021-04-12 22:47:56
【问题描述】:

我有以下提示:

export const deleteUser = (id: number) => (dispatch: ThunkDispatch<{}, {}, AnyAction>) =>
    axiosInstance.delete(`users/${id}`)
        .then(() => dispatch(deleted(id)))

我已经测试了这个 thunk:

it('creates DELETED action when user is deleted', () => {
    const deleteId: number = 1
    axiosInstance.delete.mockResolvedValue({})
    const expectedActions = [ deleted(deleteId) ];
    const store = mockStore();
    return store.dispatch(deleteUser(deleteId)).then(() => {
        expect(store.getActions()).toEqual(expectedActions)
    });
});

现在我正在测试一个发送此 thunk 的按钮。我可以复制以前的方法(将调度的动作与预期的调度动作进行比较),但这似乎没有必要,因为我已经测试了 thunk。它还需要做更多的测试设置(例如模拟 axios)

我需要做的就是测试按钮是否使用此 thunk 调用 dispatch。我试过了

beforeEach(() => {
    store = mockStore({ users: userList })
    store.dispatch = jest.fn()
    render(<Provider store={store}><UserTable /></Provider>)
});

it('should dispatch delete thunk when the delete button is clicked', () =>
    fireEvent.click(screen.getByRole('button', {name: /delete user 1/i}))
    expect(store.dispatch).toHaveBeenCalledTimes(1)
    expect(store.dispatch).toHaveBeenCalledWith(deleteUser(1))
})

expect(store.dispatch).toHaveBeenCalledWith(deleteUser(1)) 失败,因为您无法比较匿名函数。

还有其他方法,还是我需要“重新测试”组件中的 thunk?

【问题讨论】:

  • 几年前的讨论可能与您的问题有关:github.com/facebook/jest/issues/6390
  • 啊,是的,这不是一个坏主意 - 测试 2 个函数的字符串内容:expect(store.dispatch.mock.calls[0][0].toString()).toBe(deleteUser(1).toString())。不过感觉有点hacky。

标签: javascript typescript redux jestjs redux-thunk


【解决方案1】:

在考虑了更多之后,检查是否在此处分派了 thunk 并没有多大意义。我已经采用了将要测试的组件从连接的组件中分离出来的方法 - 请参阅https://stackoverflow.com/a/35578985/11550924。这使我可以编写类似的测试

const mockDeleteUser = jest.fn()
it('should call deleteUser when delete button is clicked', () => {
    render(<UserTable users={userList} deleteUser={mockDeleteUser} />)
    fireEvent.click(screen.getByRole('button', {name: /delete user 1/i}))
    expect(mockDeleteUser).toHaveBeenCalledTimes(1)
    expect(mockDeleteUser).toHaveBeenCalledWith(1)
})

即我没有模拟调度函数并检查deleteUser thunk 到达那里,而是模拟deleteUser 并检查它是否被调用。然后可以在 E2E 测试中测试连接的组件。

【讨论】:

    猜你喜欢
    • 2018-01-04
    • 2018-12-07
    • 2017-06-18
    • 1970-01-01
    • 1970-01-01
    • 2019-04-04
    • 1970-01-01
    • 2011-06-28
    • 1970-01-01
    相关资源
    最近更新 更多