Luc*_*gon 22 unit-testing reactjs react-router
如何在反应路由器v4中对组件进行单元测试?我没有成功尝试使用jest和酶对重定向进行单元测试.
我的组件:
const AppContainer = ({ location }) =>
(isUserAuthenticated()
? <AppWithData />
: <Redirect
to={{
pathname: "/login",
state: { from: location }
}}
/>);
Run Code Online (Sandbox Code Playgroud)
我尝试测试它:
function setup() {
const enzymeWrapper = mount(
<MemoryRouter initialEntries={["/"]}>
<AppContainer />
</MemoryRouter>
);
return {
enzymeWrapper
};
}
jest.mock("lib/authAPI", () => ({
isUserAuthenticated: jest.fn(() => false)
}));
describe("AppContainer component", () => {
it("renders redirect", () => {
const { enzymeWrapper } = setup();
expect(enzymeWrapper.find("<Redirect></Redirect>")).toBe(true);
});
});
Run Code Online (Sandbox Code Playgroud)
Luc*_*gon 21
回答我自己的问题.基本上我正在对我的组件做一个浅层渲染,并验证如果经过身份验证是渲染重定向组件,那么另一个是App.这里的代码:
function setup() {
const enzymeWrapper = shallow(<AuthenticatedApp />);
return {
enzymeWrapper
};
}
describe("AuthenticatedApp component", () => {
it("renders Redirect when user NOT autheticated", () => {
authApi.isUserAuthenticated = jest.fn(() => false);
const { enzymeWrapper } = setup();
expect(enzymeWrapper.find(Redirect)).toHaveLength(1);
});
it("renders AppWithData when user autheticated", () => {
authApi.isUserAuthenticated = jest.fn(() => true);
const { enzymeWrapper } = setup();
expect(enzymeWrapper.find(AppWithData)).toHaveLength(1);
});
});
Run Code Online (Sandbox Code Playgroud)
Mic*_*rry 10
这些答案都没有对我有用,并且进行了相当多的挖掘,所以我认为我会在这里汲取经验.
export const PrivateRoute = ({ component: Component, ...rest }) => (
<Route {...rest} render={(props) => (
auth.isAuthenticated
? <Component {...props} />
: <Redirect to={{
pathname: '/',
state: { from: props.location }
}} />
)} />
)
Run Code Online (Sandbox Code Playgroud)
这个测试对我没有任何问题,它PrivateComponent在auth.isAuthenticated评估时为真.
it('renders the component when the user is authorised', () => {
auth.login()
expect(auth.isAuthenticated).toBe(true)
const privateRoute = mount(
<MemoryRouter initialEntries={['/privateComponent']}>
<PrivateRoute path='/privateComponent' component={PrivateComponent} />
</MemoryRouter>
)
expect(privateRoute.find('PrivateComponent').length).toEqual(1)
})
Run Code Online (Sandbox Code Playgroud)
这是给我很多问题的测试.起初我正在检查Redirect组件.
我试着做一些像
expect(privateRoute.find('Redirect').length).toEqual(1)
Run Code Online (Sandbox Code Playgroud)
但这不行,无论我做了什么,它都找不到Redirect组件.最后,我最终检查了历史记录,但在网上找不到任何可靠的文档,最后查看了React Router代码库.
在MemoryRouter.js(第30行)中,我看到它渲染了一个Router组件.我注意到它也传递了它history作为道具,Router所以我想我可以从那里抓住它.
我最终抓住了Router使用的历史道具privateRoute.find('Router').prop('history'),然后终于给了我证据表明实际上发生了重定向,到了正确的位置,并没有减少.
it('renders a redirect when the user is not authorised', () => {
auth.logout()
expect(auth.isAuthenticated).toBe(false)
const privateRoute = mount(
<MemoryRouter initialEntries={['/privateComponent']}>
<PrivateRoute path='/privateComponent' component={PrivateComponent} />
</MemoryRouter>
)
expect(privateRoute.find('PrivateComponent').length).toEqual(0)
expect(
privateRoute.find('Router').prop('history').location.pathname
).toEqual('/')
})
Run Code Online (Sandbox Code Playgroud)
通过此测试,您将测试PrivateRoute组件的实际功能,并确保它能够正常运行.
文档还有很多不足之处.例如,我需要花费一些时间来找出initialEntries作为道具MemoryRouter,你需要这个,所以它实际上击中了路线并执行条件,我花了太长时间试图覆盖两个分支只是意识到这是什么需要.
希望这有助于某人.
这是我测试实际 URL 更改而不仅仅是Redirect页面上存在组件的最小示例:
RedirectApp.js:
import React from "react";
import { Route, Switch, Redirect } from "react-router-dom";
const RedirectApp = props => {
return (
<Switch>
<Redirect from="/all-courses" to="/courses" />
</Switch>
);
};
export default RedirectApp;
Run Code Online (Sandbox Code Playgroud)
RedirectApp.test.js:
import React from "react";
import { MemoryRouter, Route } from "react-router-dom";
import { mount } from "enzyme";
import RedirectApp from "./RedirectApp";
it("redirects /all-courses to /courses", () => {
const wrapper = mount(
<MemoryRouter initialEntries={[`/all-courses`]}>
<Route component={RedirectApp} />
</MemoryRouter>
);
expect(wrapper.find(RedirectApp).props().location.pathname).toBe("/courses");
});
Run Code Online (Sandbox Code Playgroud)
通过包裹RedirectApp在 a 中Route,MemoryRouter将react-routerprops ( match, location, and history)注入RedirectApp.
enzyme让你抓住这些props(),location道具包括pathname重定向后,所以重定向的位置可以匹配。
这种方法有点笨拙,但具有测试重定向是否会到达正确位置而不仅仅是Redirect存在的优点。
另外,您也可以export default withRouter(RedirectApp)在RedirectApp.js自动获取到react-router的道具注入。
| 归档时间: |
|
| 查看次数: |
12807 次 |
| 最近记录: |