首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JestJs:对Axios模拟实现的多个异步API调用提供相同的响应

JestJs:对Axios模拟实现的多个异步API调用提供相同的响应
EN

Stack Overflow用户
提问于 2022-01-05 21:44:42
回答 1查看 615关注 0票数 1

我有一个从API获取产品数据的方法。我使用Axios调用API。由于产品数据是相互独立的,所以我一次调用所有API,并使用Promise.all等待调用完成后再继续。例如,考虑一个函数(不包含在函数语句中),下面的行。

代码语言:javascript
复制
const productIds = [ "SKU-1", "SKU-2" ];
const promises = productIds.map<Promise<Product>>(id => axios.get(`/products/${id}`));
Promise.all(promises).then(values => {
  // do some stuff here.
});

编写的单元测试用例使用了下面的jest模拟实现。

代码语言:javascript
复制
import http from "axios";
import { sku1, sku2 } from "./test-product-data";
jest.mock("axios", () => ({
  create: jest.fn(() => http),
  get: jest.fn(() => Promise.resolve()),
}));
const httpMock = http as jest.Mocked<typeof http>;

describe("Update operations!", () => {
  beforeAll(() => {
    httpMock.get.mockImplementation(url => {
      // Call to Get product.
      if (url.endsWith("/SKU-1")) {
        mockedSuccessResponse.data = Object.assign({}, sku1);
        return Promise.resolve(mockedSuccessResponse);
      };
      if (url.endsWith("/SKU-2")) {
        mockedSuccessResponse.data = Object.assign({}, sku2);
        return Promise.resolve(mockedSuccessResponse);
      };
    });
  });
});

Jest返回上一个API调用的响应,即SKU-2的响应,甚至对于id SKU-1的产品也是如此。我是不是遗漏了什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-06 03:05:35

由于您正在修改相同的对象引用(mockedSuccessResponse.data),随后的更改将覆盖前面的更改。这意味着url的模拟对象(url)以/SKU-2结尾将覆盖mockedSuccessResponse.data。当您在axios.get()中调用promise.all时,它们都解析了sku2模拟数据。

解决方案:为不同的条件分支创建不同的模拟对象。

例如。

index.ts

代码语言:javascript
复制
import axios from 'axios';

interface Product {
  id: string;
}

export function main() {
  const productIds = ['SKU-1', 'SKU-2'];
  const promises = productIds.map<Promise<Product>>((id) => axios.get(`/products/${id}`));
  return Promise.all(promises);
}

index.test.ts

代码语言:javascript
复制
import http from 'axios';
import { main } from './';

jest.mock('axios', () => ({
  create: jest.fn(() => http),
  get: jest.fn(),
}));
const httpMock = http as jest.Mocked<typeof http>;

describe('Update operations!', () => {
  const sku1 = { id: 'sku-1' };
  const sku2 = { id: 'sku-2' };

  beforeAll(() => {
    httpMock.get.mockImplementation((url: string): any => {
      if (url.endsWith('/SKU-1')) {
        return Promise.resolve({ data: Object.assign({}, sku1) });
      }
      if (url.endsWith('/SKU-2')) {
        return Promise.resolve({ data: Object.assign({}, sku2) });
      }
    });
  });

  test('should pass', async () => {
    const actual = await main();
    expect(actual).toEqual([{ data: { id: 'sku-1' } }, { data: { id: 'sku-2' } }]);
  });
});

测试结果:

代码语言:javascript
复制
 PASS  examples/70599956/index.test.ts (9.178 s)
  Update operations!
    ✓ should pass (2 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        9.216 s
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70599956

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档