Unit testing React路由器v4重定向单元测试
如何在react router v4中对组件进行单元测试? 我尝试使用jest和Ezyme对一个带有重定向的简单组件进行单元测试,但没有成功 我的组成部分:Unit testing React路由器v4重定向单元测试,unit-testing,reactjs,react-router,Unit Testing,Reactjs,React Router,如何在react router v4中对组件进行单元测试? 我尝试使用jest和Ezyme对一个带有重定向的简单组件进行单元测试,但没有成功 我的组成部分: const AppContainer = ({ location }) => (isUserAuthenticated() ? <AppWithData /> : <Redirect to={{ pathname: "/login", st
const AppContainer = ({ location }) =>
(isUserAuthenticated()
? <AppWithData />
: <Redirect
to={{
pathname: "/login",
state: { from: location }
}}
/>);
const-AppContainer=({location})=>
(isUserAuthenticated()
?
: );
我尝试测试它:
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);
});
});
函数设置(){
常数enzymeWrapper=mount(
);
返回{
酶包装
};
}
mock(“lib/authAPI”,()=>({
isUserAuthenticated:jest.fn(()=>false)
}));
描述(“AppContainer组件”,()=>{
它(“呈现重定向”,()=>{
const{enzymeWrapper}=setup();
expect(enzymeWrapper.find(“”).toBe(true);
});
});
回答我自己的问题。
基本上,我正在对我的组件进行浅层渲染,并验证如果经过身份验证,是否正在渲染重定向组件,否则将显示应用程序。
代码如下:
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);
});
});
函数设置(){
常数enzymeWrapper=shallow();
返回{
酶包装
};
}
描述(“AuthenticatedApp组件”,()=>{
它(“当用户未授权时呈现重定向”,()=>{
authApi.isUserAuthenticated=jest.fn(()=>false);
const{enzymeWrapper}=setup();
expect(enzymeWrapper.find(Redirect)).toHaveLength(1);
});
它(“在用户授权时呈现AppWithData”,()=>{
authApi.isUserAuthenticated=jest.fn(()=>true);
const{enzymeWrapper}=setup();
expect(enzymeWrapper.find(AppWithData)).toHaveLength(1);
});
});
下面是我测试实际URL是否更改的最简单示例,而不仅仅是页面上是否存在重定向组件:
RedirectApp.js
:
从“React”导入React;
从“react router dom”导入{Route,Switch,Redirect};
const RedirectApp=props=>{
返回(
);
};
导出默认重定向应用程序;
重定向app.test.js
:
从“React”导入React;
从“react router dom”导入{MemoryRouter,Route};
从“酶”导入{mount};
从“/RedirectApp”导入RedirectApp;
它(“将/所有课程重定向到/课程”,()=>{
常量包装器=装入(
);
expect(wrapper.find(RedirectApp.props().location.pathname).toBe(“/courses”);
});
通过将重定向应用程序
包装在路由
,内存路由器
在重定向应用程序
中注入反应路由器
道具(匹配
,位置
,和历史
)
enzyme
允许您抓取这些props()
,而位置
prop在重定向后包含路径名
,因此可以匹配重定向的位置
这种方法有点老套,但它的优点是测试重定向是否正确,而不仅仅是重定向是否存在
或者,您可以在RedirectApp.js
中export default with router(RedirectApp)
,以自动获得react router
道具的注入。这两个答案对我来说都不管用,而且需要相当多的挖掘,所以我想在这里分享我的经验
privaterout.js
这次考试给了我很多问题。起初,我正在检查重定向组件
我试着做一些像
expect(privateRoute.find('Redirect').length).toEqual(1)
但这根本不起作用,无论我做了什么,它都找不到重定向组件。最后,我检查了历史记录,但在网上找不到任何可靠的文档,最后查看了React路由器代码库
在中,我看到它呈现了一个组件。我注意到它也将它的历史
作为道具传递给路由器
,所以我想我可以从那里抓到它
最后,我使用privateRoute.find('Router').prop('history')
从Router
抓取了历史道具,这最终证明确实发生了重定向,重定向到了正确的位置
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('/')
})
it('当用户未经授权时呈现重定向',()=>{
auth.logout()
expect(auth.isAuthenticated).toBe(false)
const privateRoute=挂载(
)
expect(privateRoute.find('PrivateComponent').length).toEqual(0)
期待(
privateRoute.find('Router').prop('history').location.pathname
).toEqual(“/”)
})
通过此测试,您将测试privaterout
组件的实际功能,并确保它能达到预期的目的
这些文档还有很多需要改进的地方。例如,我花了相当多的时间才找到initialEntries
,作为MemoryRouter
的道具,你需要它,所以它实际上命中了路径并执行了条件,我花了太长时间试图覆盖这两个分支,却发现这才是需要的
希望这对别人有帮助。非常好的答案非常有帮助!这是我的路线()}/>
实际上这是有效的expect(wrapper.find(Router.prop('history').location.pathname.).toEqual('/user/emptions')代码>。但不是这一行expect(wrapper.find(Redirect)).toHaveLength(1)代码>是的,这就是我的答案。在哪里定义了authApi
?
expect(privateRoute.find('Redirect').length).toEqual(1)
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('/')
})