我创建了一个recordSaga
函数,其目标是记录在传奇中分配了哪些动作。
export const recordSaga = async (saga, initialAction, state) => {
const dispatched = [];
const done = await runSaga(
{
dispatch: action => dispatched.push(action),
getState: () => state,
},
saga,
initialAction,
).done;
return {
dispatched,
done,
};
};
所以我的传奇就是这个
export function* mySaga() {
const needToSave = yield select(needToSaveDocument);
if (needToSave) {
yield put(saveDocument());
yield take(SAVE_DOCUMENT_SUCCESS);
}
yield put(doSomethingElse())
}
我想写两个测试,我希望是这样
describe('mySaga', async () => {
it('test 1: no need to save', async () => {
const state = { needToSave: false }
const { dispatched } = await recordSaga(mySaga, {}, state);
expect(dispatched).toEqual([
doSomethingElse()
])
})
it('test 2: need to save', async () => {
const state = { needToSave: true }
const { dispatched } = await recordSaga(mySaga, {}, state);
expect(dispatched).toEqual([
saveDocument(),
doSomethingElse()
])
})
})
但是,对于测试2,中间有一个take
,当然jest
(或其女友jasmine
)对我大叫:Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
< / p>
我知道这是因为runSaga
正在等待take(SAVE_DOCUMENT_SUCCESS)
,但是我该如何模拟呢?
答案 0 :(得分:1)
import React from 'react'
import Auth from '../../Authentication/Auth'
import { Redirect, Route } from 'react-router-dom'
const PrivateRoute = ({ component: Component, role, ...rest }) => (
<Route {...rest} render={props => {
const loggedIn = Auth.isAuthenticated;
if (!loggedIn) {
// not logged in so redirect to login page with the return url
return <Redirect to={{ pathname: '/login', state: { from: props.location } }} />
}
// check if route is restricted by role
if (Auth.getUserLevel() !== role) {
// role not authorised so redirect to home page
return <Redirect to={{ pathname: '/home'}} />
}
// authorised so return component
return <Component {...props} />
}} />
)
export default PrivateRoute;
使用import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Switch, Redirect } from 'react-router-dom';
import AdminPage from './Containers/AdminPage/AdminPage'
import PrivateRoute from './Components/PrivateRoute/PrivateRoute'
import Login from './Containers/Login'
class App extends Component {
cnt=0;
render() {
return (
<Wrapper>
<NavBar />
<Router>
<Switch>
<Route path="/login">
<Login />
</Route >
<PrivateRoute path="/AdminPage" Component={AdminPage} role='sm'/>
</Switch>
</Router>
</Wrapper>
)
}
}
export default App;
,您可以在第一次运行后分派。
stdChannel().put({type, payload})
; 我离开了第一个测试,因为它是预期的最终结果,但是解决方案出现在最后一个测试上。
stdChannel
答案 1 :(得分:0)
通过查看recordSaga
:
export const recordSaga = async (saga, initialAction, state) => {
似乎您应该将{type: SAVE_DOCUMENT_SUCCESS}
作为第二个参数(即initialAction
)传递。那应该触发take
效果。