2017-06-01 116 views
7

如何在响应路由器v4中测试组件? 我尝试使用jest和酶对重定向进行单元测试时失败。React Router v4重定向单元测试

我的组件:

const AppContainer = ({ location }) => 
    (isUserAuthenticated() 
    ? <AppWithData /> 
    : <Redirect 
     to={{ 
      pathname: "/login", 
      state: { from: location } 
     }} 
     />); 

我试图对它进行测试:

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); 
    }); 
}); 

回答

10

回答我的问题。 基本上我做了我的组件的浅层渲染,并验证如果通过身份验证是呈现重定向组件,否则应用程序之一。 下面的代码:

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); 
    }); 
}); 
0

这是我测试的小例子,实际的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; 

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"); 
}); 

通过在Route中包裹RedirectApp,MemoryRouter注入RedirectApp中的react-router道具(matchlocationhistory)。

enzyme让你抓住这些props()location道具包括重定向后pathname,所以重定向的位置可以匹配。

这种方法有点哈克,但测试的优点是,重定向要去正确的地方,不只是一个Redirect存在。

或者,您可以export default withRouter(RedirectApp)RedirectApp.js自动获取react-router道具注入。