【发布时间】:2017-03-04 18:11:24
【问题描述】:
所以,假设我有下一步行动:
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()
};
};
}
我想为它添加测试,以增加代码的可靠性。
所以,这里有几件事:
- 我们发送身份验证标头并获取数据作为响应
- 如果响应中存在错误,我们会抛出错误
- 我们设置了所有需要的令牌,发送所有需要的操作以表明我们现在已经登录了
- 获取客户端数据
- 根据参数和接收到的数据,我们重定向到需要的路由/不重定向
问题是测试真的太难了,我们需要对所有东西都进行存根,这很糟糕,因为测试很脆弱,脆弱性和对实现的了解太多(更不用说存根调度非常具有挑战性)正常工作)。
因此,我应该测试所有这 5 点,还是只关注最重要的东西,例如发送授权请求、抛出错误和检查重定向?我的意思是,所有标志都可以更改的问题,所以它不是那么可靠。
另一种解决方案是将这些活动分成如下内容:
authsetLoginInfohandleRedirects
并通过依赖注入传递所有需要的函数来调用(这里基本上只是使用参数)?使用这种方法,我只能监视调用此函数,而无需详细说明。
我对纯函数的单元测试和为它们处理不同的边缘情况非常满意(无需测试太多的实现,只测试结果),但测试具有副作用的复杂函数对我来说真的很难。
【问题讨论】:
-
我的直觉是,您应该从 thunk 动作创建器中提取大量逻辑,并将其放入由动作创建器调用的单独实用程序函数中。您列出的 5 个步骤中的每一个都应该有自己的测试。
-
但它不是一个实用函数,它完全是业务逻辑。是的,我可以让它们变得纯粹——但我基本上需要检查它们是否被调用,否则它的实现细节太多了。
-
什么意思?我要说的是,这个动作创建者的逻辑太多了。您应该制作额外的函数,作为实用函数提供给动作创建者,以提高模块化。
-
它们不能是
utility函数,因为它们都有副作用。问题是如何将它们分开以及如何测试整个流程。 -
你能给我链接一个说实用函数不能有副作用的资源吗?
标签: javascript unit-testing asynchronous redux redux-thunk