为什么redux模拟商店没有';不显示在捕获承诺中发送的操作?
当涉及到标题问题时,我很糟糕,对此我很抱歉 我的问题是: 我正在按照建议对我的异步redux操作进行单元测试。我使用为什么redux模拟商店没有';不显示在捕获承诺中发送的操作?,redux,redux-thunk,nock,redux-mock-store,Redux,Redux Thunk,Nock,Redux Mock Store,当涉及到标题问题时,我很糟糕,对此我很抱歉 我的问题是: 我正在按照建议对我的异步redux操作进行单元测试。我使用nock模拟API调用,并使用redux模拟存储检查调度的操作。到目前为止,它工作得很好,但我有一个测试失败了,尽管它显然确实有效。已调度的操作既不会显示在由store.getActions()返回的数组中,也不会在store.getState()中更改状态。我确信它确实会发生,因为我可以在手动测试时看到它,并使用Redux开发工具观察它 在这个动作分派中唯一不同的是,它在一个承诺
nock
模拟API调用,并使用redux模拟存储
检查调度的操作。到目前为止,它工作得很好,但我有一个测试失败了,尽管它显然确实有效。已调度的操作既不会显示在由store.getActions()
返回的数组中,也不会在store.getState()
中更改状态。我确信它确实会发生,因为我可以在手动测试时看到它,并使用Redux开发工具观察它
在这个动作分派中唯一不同的是,它在一个承诺中被调用,而在另一个承诺中被捕获。(我知道这听起来很混乱,看看代码就知道了!)
我的代码是什么样子的:
动作:
export const login = (email, password) => {
return dispatch => {
dispatch(requestSession());
return httpPost(sessionUrl, {
session: {
email,
password
}
})
.then(data => {
dispatch(setUser(data.user));
dispatch(push('/admin'));
})
.catch(error => {
error.response.json()
.then(data => {
dispatch(setError(data.error))
})
});
};
}
it('should create a SET_SESSION_ERROR action', () => {
nock(/example\.com/)
.post(sessionPath, {
session: {
email: fakeUser.email,
password: ''
}
})
.reply(422, {
error: "Invalid email or password"
})
const store = mockStore({
session: {
isFetching: false,
user: null,
error: null
}
});
return store.dispatch(actions.login(
fakeUser.email,
""))
.then(() => {
expect(store.getActions()).toInclude({
type: 'SET_SESSION_ERROR',
error: 'Invalid email or password'
})
})
});
这个httpPost
方法只是fetch
的包装器,如果状态代码不在200-299范围内,它就会抛出,如果没有失败,它已经将json解析为一个对象。我可以在这里添加它,如果它看起来相关的话,但我不想让它比现在更长
没有显示的操作是dispatch(setError(data.error))
测试:
export const login = (email, password) => {
return dispatch => {
dispatch(requestSession());
return httpPost(sessionUrl, {
session: {
email,
password
}
})
.then(data => {
dispatch(setUser(data.user));
dispatch(push('/admin'));
})
.catch(error => {
error.response.json()
.then(data => {
dispatch(setError(data.error))
})
});
};
}
it('should create a SET_SESSION_ERROR action', () => {
nock(/example\.com/)
.post(sessionPath, {
session: {
email: fakeUser.email,
password: ''
}
})
.reply(422, {
error: "Invalid email or password"
})
const store = mockStore({
session: {
isFetching: false,
user: null,
error: null
}
});
return store.dispatch(actions.login(
fakeUser.email,
""))
.then(() => {
expect(store.getActions()).toInclude({
type: 'SET_SESSION_ERROR',
error: 'Invalid email or password'
})
})
});
谢谢你的阅读
编辑:
setError
操作:
const setError = (error) => ({
type: 'SET_SESSION_ERROR',
error,
});
httpPost
方法:
export const httpPost = (url, data) => (
fetch(url, {
method: 'POST',
headers: createHeaders(),
body: JSON.stringify(data),
})
.then(checkStatus)
.then(response => response.json())
);
const checkStatus = (response) => {
if (response.status >= 200 && response.status < 300) {
return response;
}
const error = new Error(response.statusText);
error.response = response;
throw error;
};
export const httpPost=(url,数据)=>(
获取(url{
方法:“POST”,
headers:createHeaders(),
正文:JSON.stringify(数据),
})
.然后(检查状态)
.then(response=>response.json())
);
const checkStatus=(响应)=>{
如果(response.status>=200&&response.status<300){
返回响应;
}
常量错误=新错误(response.statusText);
error.response=响应;
投掷误差;
};
因为您在catch方法中使用嵌套异步函数-您需要返回承诺:
.catch(error => {
return error.response.json()
.then(data => {
dispatch(setError(data.error))
})
});
否则,将在断言后调用dispatch
参见基本示例:-不返回
-返回后如果有一个
redux mock store
标签就好了。它应该在路上:)请添加一个setError@fahrradflucht如果答案正确,请标记为正确。