dan*_*son 3 unit-testing reactjs jestjs react-router-v4 react-testing-library
我正在尝试测试登录组件。具体来说,它会在成功登录时重定向。手动测试时它工作正常。但在我的测试中,它从不进行重定向,因此找不到“注销”链接:
test('successfully logs the in the user', async () => {
const fakeUserResponse = {success: true, token: 'fake_user_token'}
jest.spyOn(window, 'fetch').mockImplementationOnce(() => {
return Promise.resolve({
json: () => Promise.resolve(fakeUserResponse),
})
})
const { getByText, getByLabelText, findByTestId } = render(<Router><Login /></Router>)
fireEvent.change(getByLabelText(/email/i), {target: {value: 'dan@example.com'}})
fireEvent.change(getByLabelText(/password/i), {target: {value: 'password1234'}})
fireEvent.click(getByText(/submit/i))
await waitForElement(() => getByText(/logout/i));
})
Run Code Online (Sandbox Code Playgroud)
我正在使用react-router版本 4 进行重定向,如下所示:
{state.resolved ? <Redirect to="/" /> : null}
Run Code Online (Sandbox Code Playgroud)
我会以错误的方式解决这个问题吗?
Mat*_*prz 10
就我而言,这可以完成工作:
it('should do stuff and redirect to /some/route', async () => {
// given
const history = createMemoryHistory();
// when
render(<Router history={history}><MyComponent /></Router>);
// do stuff which leads to redirection
// then
await waitFor(() => {
expect(history.location.pathname).toBe('/some/route');
});
});
Run Code Online (Sandbox Code Playgroud)
小智 9
我个人模拟了组件history.replace使用的函数Redirect。
const history = createBrowserHistory();
history.replace = jest.fn();
render(
<Router history={history} >
<Component />
</Router>
);
// trigger redirect
expect(history.replace).toHaveBeenCalledWith(expect.objectContaining({
"pathname": "/SamplePath",
"search": "?SampleSearch",
"state": { "Sample": "State" }
}));
Run Code Online (Sandbox Code Playgroud)
这使您不仅可以检查正确的路径。请确保您正在使用Router而不是BrowserRouter在测试中。后者不接受历史道具。
您可以模拟Redirect组件的实现以显示一些包含路径的文本,而不是重定向到它:
jest.mock('react-router-dom', () => {
return {
Redirect: jest.fn(({ to }) => `Redirected to ${to}`),
};
});
Run Code Online (Sandbox Code Playgroud)
并期望您的组件以正确的路径显示文本:
expect(screen.getByText('Redirected to /')).toBeInTheDocument();
Run Code Online (Sandbox Code Playgroud)
所以我最终这样做了:
const { getByText, getByLabelText, } = render(
<Router>
<Login/>
<Switch>
<Route path="/">
<div>logged out</div>
</Route>
</Switch>
</Router>
)
fireEvent.change(getByLabelText(/email/i), {target: {value: 'dan@example.com'}})
fireEvent.change(getByLabelText(/password/i), {target: {value: 'password1234'}})
fireEvent.click(getByText(/submit/i))
await waitForElement(() => getByText(/logged out/i))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5293 次 |
| 最近记录: |