5

如何模拟特定的 axios 调用?想象一下 2 次 GET 调用:

await axios.get('api/numbers');
await axios.get('api/letters');

然后这是在测试中发生的:

const mockGet = jest.spyOn(axios, 'get');
mockGet.mockReturnValueOnce(Promise.resolve({ data: 1 }));
mockGet.mockReturnValueOnce(Promise.resolve({ data: 'a' }));

如何mockReturnValueOnce根据传递给 axios 的 url 创建条件(例如 for 'api/numbers'-> return Promise.resolve({ data: 1 })

4

1 回答 1

7

到目前为止,还没有方法jestjs可以做到这一点。这是建议:参数化模拟返回值

以下是解决方案:

  1. 利用sinon.js

sinon.js支持根据参数模拟返回值,有一个方法名为stub.withArgs(arg1[, arg2, ...]);

  1. 使用jest-when - A when(fn).calledWith(args).thenReturn(value) lib 开玩笑

  2. 如果您坚持使用jestjs, since会mockReturnValueOnce按顺序返回值(第一次调用、第二次调用等)。您可以使用以下方式:

index.js

import axios from 'axios';

export async function main() {
  const numbersRes = await axios.get('api/numbers');
  const lettersRes = await axios.get('api/letters');
  return { numbersRes, lettersRes };
}

index.test.js

import { main } from '.';
import axios from 'axios';

describe('59751925', () => {
  it('should pass', async () => {
    const mockGet = jest.spyOn(axios, 'get');
    mockGet.mockImplementation((url) => {
      switch (url) {
        case 'api/numbers':
          return Promise.resolve({ data: 1 });
        case 'api/letters':
          return Promise.resolve({ data: 'a' });
      }
    });
    const actual = await main();
    expect(actual.numbersRes).toEqual({ data: 1 });
    expect(actual.lettersRes).toEqual({ data: 'a' });
  });
});

单元测试结果:

 PASS  src/stackoverflow/59751925/index.test.js (11.168s)
  59751925
    ✓ should pass (9ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        13.098s
于 2020-01-16T13:17:13.377 回答