那么,假设我有下一步行动:
export function login({ email, password, redirectTo, doNotRedirect }) {
return ({ dispatch }) => {
const getPromise = async () => {
const basicToken = Base64.encode(`${email}:${password}`);
const authHeaders = { Authorization: `Basic ${basicToken}` };
const { payload, error } = await dispatch(sendAuthentication(authHeaders));
if (error) throw payload;
const { username, token, fromTemporaryPassword } = payload;
const encodedToken = Base64.encode(`${username}:${token}`);
dispatch(persistence.set('authorizationToken', encodedToken));
dispatch(postGlobalId({ username }));
dispatch(setIsLoggedIn(true));
dispatch(setIsFromTemporaryPassword(fromTemporaryPassword));
await dispatch(clientActions.fetchClient);
if (doNotRedirect) return;
if (fromTemporaryPassword)
dispatch(updatePath('/profile/change-password'));
else
dispatch(updatePath(redirectTo || '/dashboard'));
};
return {
type: AUTHENTICATION_LOGIN,
payload: getPromise()
};
};
}
我想为它添加测试,以增加代码的可靠性。
所以,这里有几件事:
- 我们发送身份验证 header 并获取数据作为响应
- 如果响应中存在错误,我们将抛出一个错误
- 我们设置所有需要的 token ,发送所有需要的操作来表明我们现在已经登录
- 获取客户数据
- 根据参数和接收到的数据,我们重定向到需要的路由/不重定向
问题是它真的太难测试了,我们需要对所有东西进行 stub ,这很糟糕,因为脆弱的测试、脆弱性和太多的实现知道(更不用说 stub 调度到正常工作)。
因此,我应该测试所有这 5 点,还是只关注最重要的东西,比如发送授权请求、抛出错误和检查重定向?我的意思是,所有标志都可以更改的问题,所以它不那么可靠。
另一种解决方案是将这些事件分为以下内容:
授权
setLoginInfo
处理重定向
并通过依赖注入(inject)传递所有需要的函数来调用(这里基本上只是使用参数)?通过这种方法,我可以仅监视此函数的调用,而无需深入了解更多细节。
我很乐意对纯函数进行单元测试并为它们处理不同的边缘情况(无需测试太多实现,只测试结果),但测试具有副作用的复杂函数对我来说真的很难。
最佳答案
如果你有像这样非常复杂的 Action ,我认为另一种(更好?)方法是使用简单的同步 Action (你甚至可以直接分派(dispatch)有效负载,如果你愿意,可以放弃 Action 创建者,减少样板) ,并使用 redux-saga 处理异步端:https://github.com/yelouafi/redux-saga
Redux Saga 可以非常简单地将您的业务逻辑代码分解为多个可以单独测试的简单生成器函数。由于该库中的“调用”功能,它们甚至可以在不调用底层 API 方法的情况下进行测试:http://yelouafi.github.io/redux-saga/docs/api/index.html#callfn-args .由于使用了生成器,您的测试可以使用标准的 iterator.next 方法将值“提供”给 saga。最后,它们使 reducer 更容易发表意见,因为您可以检查存储状态中的某些内容(例如,使用选择器)以查看您的 saga 中下一步要做什么。
如果 Redux + Redux Saga 在我开始开发我的应用程序之前就已经存在(到目前为止大约有 100,000 个 JS(X) LOC),我肯定会使用它们。
关于javascript - 测试复杂的异步 Redux 操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40193466/