【问题标题】:how to have jest resolve promises in order different than promises were called?如何让 jest 以不同于调用承诺的顺序解决承诺?
【发布时间】:2021-09-08 02:22:28
【问题描述】:

我正在使用 Axios 向我的服务器发出请求。我知道如何模拟 Axios 并为我的测试代码提供正面和负面的结果。但是今天我遇到了一个情况,我的代码调用了两个 api 端点并正确地测试逻辑,我需要能够控制它们被解析的顺序。

不做任何特别的事情,我开玩笑会先解决第一个电话,然后再解决第二个电话。但我需要确保我的代码可以处理以相反顺序解析的调用。在解决第一个电话之前,我不知道如何开玩笑来解决第二个电话。

被测代码的一个简单示例是:

function underTest() { 
   axios.request('get', url1).then(() => { do something });
   axios.request('get', url2).then(() => { do something else });
}

当“做某事”和“做其他事情”在两个序列中运行时,我必须确保代码做正确的事情。

@Bergi 问我现在是如何模拟 Axios 请求的,所以来吧。

在我的生产代码中,我使用 NTypewriter 为后端的每个 C# 控制器创建 Typescript 类。它产生这样的东西:

export class LeagueService {
     public static getManagementSummaryRoute = (leagueId: number) => `/api/League/${leagueId}/ManagementSummary`;
     public static getManagementSummary(leagueId: number) : Promise<LeagueManagementSummary> {
         return MakeRequest<LeagueManagementSummary>("get", this.getManagementSummaryRoute(leagueId), null);
}

MakeRequest 在哪里:

import axios, { AxiosResponse, Method } from 'axios';

export async function MakeRequest<T>(httpMethod: Method, url: string, 
payload: any | undefined = null): Promise<T>
{
  const r = await axios.request({
    method: httpMethod,
    url,
    data: payload
  });
  return r.data;
}

这让我可以像这样喊到终点:

  BoxLeagueService.getSession(this.leagueId, this.sessionId)
    .then((newData: SessionBox) => {
      box.updateData(newData);
    })
    .catch();

好的,那么在单元测试代码中,我要导入 axios 并模拟它。 Jest 对 axios 的支持非常好。

import axios from 'axios';
jest.mock('axios');
const mockedAxios = axios as jest.Mocked<typeof axios>;

然后在测试中,我会这样做:

it('constructor should request the league info with live layout When preview is false', () => {
   // Arrange
   mockedAxios.request.mockResolvedValueOnce({ data: leagueInfo });
   mockedAxios.request.mockClear();
   // Act
   model = new BLInfoModel(leagueIdStr, false);
   // Assert
   expect(mockedAxios.request).toHaveBeenCalledWith({
     method: 'get',
     url: BoxLeagueService.infoPageRoute(leagueId, false),
     data: null
   });
});

数据:leagueInfo 是我从服务器提供的数据。我将这些 .json 文件存储在一个名为 json 的文件夹中,以便我可以轻松找到它们并轻松添加到它们。

我只是将它们导入到文件顶部的单元测试中,如下所示:

// Test Data
import leagueInfo from './__json__/LeagueInfo.json';

当我很高兴按照 axios 请求的调用顺序完成 axios 请求时,这一切都很好。但是今天,在这样做多年之后,我遇到了一种情况,我想测试以相反的顺序解决两个请求仍然产生正确的结果。

【问题讨论】:

  • 你能告诉我们你目前是如何嘲笑axios.request的吗?

标签: javascript jestjs


【解决方案1】:

then 回调中,您可以定义一些超时,设置不同的超时值,具体取决于哪个应该首先/最后解决

const delay = (ms) => () => new Promise((res) => setTimeout(res, ms))
axios.request('get', url1)
   .then(delay(10))
   .then(() => { do something }); // resolves first
axios.request('get', url2)
   .then(delay(20))
   .then(() => { do something else }); // resolves last

编辑...

我刚刚意识到这可能是您的生产代码,而不是测试代码。无论哪种方式,您都可以将相同的东西应用于 axios 模拟,即对链式 then 回调应用延迟

【讨论】:

  • 是的,这是我的生产代码,因此无法添加延迟。我必须考虑如何将 deleys 添加到模拟实现中......
猜你喜欢
  • 1970-01-01
  • 2020-02-12
  • 1970-01-01
  • 2015-12-22
  • 1970-01-01
  • 2019-09-29
  • 2018-03-19
  • 2020-09-07
  • 2015-11-17
相关资源
最近更新 更多