Unit testing React路由器v4重定向单元测试

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

如何在react router v4中对组件进行单元测试? 我尝试使用jest和Ezyme对一个带有重定向的简单组件进行单元测试,但没有成功

我的组成部分:

 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('/')
})