2017-10-28 69 views
0

我試圖驗證我的路由是否正確設置。就像在我有一個特定的URI的時候,那麼相應的組件就會被加載。只是爲了防止我意外地迷路。用redux連接組件測試react-router v4路由

下面是一個示例連接頁:

import React from 'react'; 
import {connect} from 'react-redux'; 

export const ConnectPage = (props) => { 
    return <div>{props.code}</div>; 
}; 

export default connect(
    (state) => ({}), 
    (dispatch) => ({}) 
)(ConnectPage); 

主頁:

import React from 'react'; 
import LoginPage from './LoginPage'; 

const MainPage =() => (
    <LoginPage/> 
); 

export default MainPage; 

這裏是我的路線文件:

import React from 'react'; 
import {Route, Switch, Redirect} from 'react-router-dom'; 
import qs from 'query-string'; 

import MainPage from './MainPage'; 
import ConnectPage from './ConnectPage'; 

class Routes extends React.Component { 

    render() { 
    return (<Switch> 
     <Route path={'/connect/:provider'} render={(matches) => { 
     const search = qs.parse(matches.location.search); 

     if (search.code) { 
      return <ConnectPage code={search.code}/>; 
     } 

     return <Redirect to={'/'}/>; 

     }}/> 
     <Route exact path={'/'} component={MainPage}/> 
    </Switch> 
    ); 
    } 
} 

export default Routes; 

而這裏的是我遇到的麻煩我的測試:

import React from 'react'; 
import {mount} from 'enzyme'; 
import {MemoryRouter} from 'react-router'; 
import configureStore from 'redux-mock-store'; 
import Chance from 'chance'; 

import Routes from './Routes'; 

import MainPage from './MainPage'; 
import ConnectPage from './ConnectPage'; 
import {createProvider as Provider} from 'react-redux'; 

const chance = new Chance(); 

const middlewares = []; 
let mockStore; 

describe('The Routes',() => { 

    beforeAll(()=>{ 
    mockStore = configureStore(middlewares); 
    }); 

    it('loads the Main Page on /',() => { 
    const component = mount(
     <MemoryRouter initialEntries={['/']} initialIndex={0}> 
     <Routes store={mockStore}/> 
     </MemoryRouter> 

    ); 
    expect(component.find(MainPage).length).toBe(1); 

    }); 

    it('redirects to the main page if no code',() => { 
    const url = '/connect/someprovider'; 

    const component = mount(
     <MemoryRouter initialEntries={[url]} initialIndex={0}> 
     <Routes/> 
     </MemoryRouter> 
    ); 

    expect(component.find(MainPage).length).toBe(1); 

    }); 

    it('loads the Connect Page on /connect/provider',() => { 
    const code = chance.word({length: 32}); 
    const url = `/connect/provider?code=${code}`; 

    const component = mount(
     <Provider store={mockStore}> 
     <MemoryRouter initialEntries={[url]} initialIndex={0}> 
      <Routes/> 
     </MemoryRouter> 
     </Provider>); 

    try { 
     expect(component.find(ConnectPage).length).toBe(1); 
    } catch (e) { 
     console.log('Used url:', url); 
     throw (e); 
    } 

    }); 

}); 

我不能爲我的生活弄清楚如何進行第三次測試。我只想確保在適當的時候將ConnectedPage放置到位。

在這種狀態下,我得到:

Warning: Functions are not valid as a React child. This may happen if you return a Component instead of <Component /> from render. Or maybe you meant to call this function rather than return it. 
     in createProvider (created by WrapperComponent) 
     in WrapperComponent 

回答

0

我發現在此期間的答案,所以我將它張貼在這裏繁榮。如果你知道更好,請告訴我!

下面是修改後的測試案例:

it('loads the Connect Page on /connect/provider',() => { 
    const code = chance.word({length: 32}); 
    const url = `/connect/provider?code=${code}`; 

    const component = mount(
     <MemoryRouter initialEntries={[url]} initialIndex={0}> 
     <Routes/> 
     </MemoryRouter>, 
     { 
     context: { 
      store: mockStore() 
     }, 
     childContextTypes: { 
      store: PropTypes.object.isRequired 
     } 
     }); 

    try { 
     expect(component.find(ConnectPage).length).toBe(1); 
    } catch (e) { 
     console.log('Used url:', url); 
     throw (e); 
    } 

    }); 

調用mockStore似乎是主要的解決方案,而不是僅僅把它當作是在上下文。我不確定爲什麼這個工作,但它確實。我現在會一起滾動它,但很想聽到一些解釋,以便我可以學習。

+0

因此,我發現我的方式的錯誤...'mockStore'確實是一個功能,你需要通過初始狀態......我與stoopid ... – meza