在 Redux 的编写测试部分,http://rackt.org/redux/docs/recipes/WritingTests.html ,如果 store.dispatch 实际上是在调用 actions.fetchTodos,store.dispatch(actions.fetchTodos())
如何不调用 fetch 方法?
it('creates FETCH_TODOS_SUCCESS when fetching todos has been done', (done) => {
nock('http://example.com/')
.get('/todos')
.reply(200, { todos: ['do something'] })
const expectedActions = [
{ type: types.FETCH_TODOS_REQUEST },
{ type: types.FETCH_TODOS_SUCCESS, body: { todos: ['do something'] } }
]
const store = mockStore({ todos: [] }, expectedActions, done)
store.dispatch(actions.fetchTodos())
})
每次我尝试运行与此类似的东西时,我总是得到一个 fetch is not defined。即使我使用诺克。所以我必须监视我的 Action ,以免接到提取电话。
这是我的单元测试:
it('should request a password reset, and then return success on 200', (done) => {
nock('http://localhost:8080/')
.post('/password-reset-requests')
.reply(200);
var email = "test@email.com";
const expectedActions=[
{type: REQUEST_ADD_PASSWORD_RESET_REQUEST},
{type: REQUEST_ADD_PASSWORD_RESET_REQUEST_SUCCESS}
];
const store = mockStore({}, expectedActions, done);
store.dispatch(Actions.addPasswordResetRequest());
这是 Action :
export default function addPasswordResetRequest(email){
return dispatch => {
dispatch(requestAddPasswordResetRequest(email));
return addPasswordResetRequestAPI(email)
.then(() =>{
dispatch(requestAddPasswordResetRequestSuccess());
})
.catch((error) => {
dispatch(requestAddPasswordResetRequestFailure(error));
});
};
}
以及调用fetch的函数:
export const addPasswordResetRequestAPI = (email) => {
return fetch(
SETTINGS.API_ROOT + '/password-reset-requests',
{
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
email: email,
code: NC_SETTINGS.GROUP.code
})
}
)
.then(handleResponse);
};
我不确定我正在做的方式是否足以满足测试操作的目的,但我确实遇到了 store.dispatch 只返回 expectedActions 的第一个元素的问题,它不等于我在 spy addPasswordResetRequest 中提供的列表。下面包括 spy 事件。
it('should request a password reset, and then return success on 200', (done) => {
nock('http://localhost:8080/')
.post('/password-reset-requests')
.reply(200);
Actions.addPasswordResetRequest = spy(() => {
return ([
{type: REQUEST_ADD_PASSWORD_RESET_REQUEST},
{type: REQUEST_ADD_PASSWORD_RESET_REQUEST_SUCCESS}
]
);
});
var email = "test@email.com";
const expectedActions=[
{type: REQUEST_ADD_PASSWORD_RESET_REQUEST},
{type: REQUEST_ADD_PASSWORD_RESET_REQUEST_SUCCESS}
];
const store = mockStore({}, expectedActions, done);
store.dispatch(Actions.addPasswordResetRequest());
最佳答案
“addPasswordResetRequest”操作不是按说的操作。
这是一个包含3个子 Action 的复合 Action
startAction =requestAddPasswordResetRequest,
successAction =requestAddPasswordResetRequestSuccess
failAction =requestAddPasswordResetRequestFailure
我通常会分别测试每个 Action 。所以我会有类似的东西
describe("requestAddPasswordResetRequest", () => {
it("shows the loading spinner or whatever", ...);
it("does some other state change maybe", ...);
});
describe("requestAddPasswordResetRequestSuccess", () => {
it("hides the loading spinner or whatever", ...);
it("changes the password state or something", ...);
});
describe("requestAddPasswordResetRequestFailure", () => {
it("hides the loading spinner or whatever", ...);
it("shows the error somehow", ...);
});
//each test would be something like
it("changes the password state or something", ()=>{
const action = requestAddPasswordResetRequestSuccess({
some : "payload from the server"
});
const newState = myReducer({ state : "somestate" }, action);
expect(newState).to.be.eql("expected result for that action");
});
请注意在测试中我不需要商店或任何异步逻辑。这就是 redux 的美妙之处(以及一般的功能性东西),它很简单:)
在此之后,我会对整个事情进行单独的测试,并确保复合 Action 分派(dispatch)正确的简单 Action ,在复合 Action 中我会模拟所有东西(包括存储和“获取”东西,因为我只想测试 Action 是否以正确的顺序触发)。
如果 Action 以正确的顺序分派(dispatch)并且每个 Action 分开工作,我将非常有信心事情会按预期工作。
希望这对您有所帮助。
关于javascript - 我们如何在 Redux 异步操作中模拟获取?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34517395/