我有一个与第三方API交互的函数,因此结果根据不同的条件而不同。
export const getDataFromAPI = async (): Promise <any> => {
try {
let data = [];
if ( /* data already exists and is updated on local cache*/ ) {
data = /* get data from local cache */;
return {
data: data,
pageLoading: false
};
} else {
const response = /*get data from an external API*/;
if ( /* data on API server was not up to date */ ) {
return {
error: 'The data is not updated for the current month. Please contact our support team',
pageLoading: false
};
} else {
/* data on API server was up to date */
return {
data: response.data,
pageLoading: false
};
}
}
} catch (ex) {
return {
error: 'An error occured'
};
}
}
这个函数不接受任何参数,根据不同的内部条件返回不同的输出。
为了写一个测试用例,我需要提前知道未来可能的结果。
在这种情况下--我看不到任何预测未来的方法。当考虑为这个函数写一个测试时,我的生活变得很困难!!!
解释一下--我是这样写测试用例的。
test("getDataFromAPI function", async () => {
const actualResult = await getDataFromAPI();
const expectedResult = ?????;
expect(actualResult).toEqual(expectedResult);
});
应该是什么 expectedResult
?
思考这个问题的一种方法是将函数逻辑与实际的数据API分开。单元测试将帮助你行使函数中的所有逻辑(包括所有分支)。 在你的函数中有4条代码路径。
单元测试可以锻炼每一个逻辑分支,给你反馈你的函数工作......独立于数据源。
一个允许你琐碎地执行所有4个分支的重构是注入缓存和服务api。函数可以接受这两个参数,如果没有提供这两个参数,则回退到当前的定义。
export const getDataFromAPI = async (cache, service): Promise <any> => {
cache = cache || currentCacheImpl;
service = service || currentServiceImpl;
}
这允许你在单元测试中配置一个缓存和服务,返回精确的响应,以触发你的函数的每个逻辑分支!
可测试性和可验证性是代码的一个特点! 行使每个分支可以让你确定你的函数是否正确工作。在它进行单元测试之后,问题就变成了验证你的函数 其实 与现实生活中的数据源和缓存一起工作。