如何在没有固定结果的情况下测试与第三方API交互的函数?

问题描述 投票:1回答:1

我有一个与第三方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?

?

  • 我写的代码很丑吗?
  • 有没有可能对这个函数进行重构以允许编写测试用例?
javascript typescript unit-testing jestjs tdd
1个回答
1
投票

思考这个问题的一种方法是将函数逻辑与实际的数据API分开。单元测试将帮助你行使函数中的所有逻辑(包括所有分支)。 在你的函数中有4条代码路径。

  • 本地缓存中的数据
  • 数据不在本地缓存中,服务器更新了。
  • 数据不在本地缓存中,服务器没有更新。
  • 异常处理案例

单元测试可以锻炼每一个逻辑分支,给你反馈你的函数工作......独立于数据源。

一个允许你琐碎地执行所有4个分支的重构是注入缓存和服务api。函数可以接受这两个参数,如果没有提供这两个参数,则回退到当前的定义。

export const getDataFromAPI = async (cache, service): Promise <any> => {
   cache = cache || currentCacheImpl;
   service = service || currentServiceImpl;
}

这允许你在单元测试中配置一个缓存和服务,返回精确的响应,以触发你的函数的每个逻辑分支!


可测试性和可验证性是代码的一个特点! 行使每个分支可以让你确定你的函数是否正确工作。在它进行单元测试之后,问题就变成了验证你的函数 其实 与现实生活中的数据源和缓存一起工作。

© www.soinside.com 2019 - 2024. All rights reserved.