【问题标题】:How to mock and test Axios rejected promise?如何模拟和测试 Axios 拒绝的承诺?
【发布时间】:2020-11-21 21:22:06
【问题描述】:

我创建了一个名为 API 的类,它是 Axios 的简单包装器

export class API {    
  static get = async (route: string, version: string = API_VERSION) => {
    try {
      return await axios.get(`${BASE_URL + version}${route}`);
    } catch (error) {
      throw error;
    }
  };
}

我正在尝试测试get方法的catch分支:

我试过了:

describe('API Throws Errors', () => {
  beforeEach(() => {
    // axios.get.mockImplementation(() => Promise.reject('rejected'));
    jest.mock('axios', () => ({
      get: jest.fn().mockReturnValue(Promise.reject('error'))
    }));
  });

  it('get fails', async () => {
    await expect(() => {
      API.get(GROUPS.url());
    }).rejects.toEqual('error');
  });

  afterEach(() => {
    jest.clearAllMocks();
  });
});

【问题讨论】:

  • 您可以尝试将 get 包装在箭头函数中吗? await expect(() => { API.get(“bad_url”) }).toThrowError(“whatever”)
  • 当我这样做时它说“函数没有抛出”
  • jest.mock('axios', () => ... 在 beforeEach 中效率低下。如果它已经是一个模拟,你可以继续使用axios.get.mockImplementation...

标签: javascript jestjs axios


【解决方案1】:

toThrowError() 应该针对函数断言而不是结果,因为如果函数调用发生错误,expect 没有机会被评估。它仅适用于抛出错误的常规函数​​。它不适用于async 函数,因为它们不会抛出错误而是返回结果,这会拒绝承诺。

rejects.toThrowError() 构造是一种断言被拒绝的承诺的方式,需要为断言提供承诺而不是返回它的函数:

await expect(API.get("bad_url")).rejects.toThrowError();

【讨论】:

  • 你不会得到同样的错误,await expect(() => { API.get(GROUPS.url()); }).rejects.toEqual('error'); 不是答案中建议的。请完全使用建议的代码。
  • 我得到了完全相同的错误。我用代码和错误更新了 OP
  • 您仍在使用错误的代码。考虑按原样粘贴。它应该是await expect(API.get(GROUPS.url())...,而不是await expect(() => { API.get(GROUPS.url()) })...。它应该提供一个承诺,而不是一个功能。可能答案没有解释清楚为什么会这样,我更新了。
【解决方案2】:

您可以使用jest.mock 模拟axios.get 的行为。将以下代码放在describe 部分上方:

jest.mock('axios', () => ({
  get: jest.fn().mockReturnValue(Promise.reject('error'))
}));

然后你测试如下错误:

it('get fails', async () => {
    await expect(API.get("bad_url")).rejects.toEqual('error');
});

准确代码

jest.mock('axios', () => ({
    get: jest.fn().mockReturnValue(Promise.reject('error')),
}));

describe('API Throws Errors', () => {
    it('get fails', async () => {
        await expect(API.get(GROUPS.url())).rejects.toEqual('error');
    });
});

注意

如果你有另一个不应该失败的测试用例,你可以模拟它返回Promise.resolve()。或者您可以简单地清除模拟。

describe('API Throws Errors', () => {
    it('get fails', async () => {
        await expect(API.get(GROUPS.url())).rejects.toEqual('error');
    });
    
    it('should success', async () => {
        Axios.get.mockReturnValue(Promise.resolve(SOME_VALUE));
        await expect(API.get(GROUPS.url())).resolves.toEqual(SOME_VALUE);
    });
});

【讨论】:

  • 我试过了,但出错了:Received has type: function Received has value: [Function anonymous]我更新了 OP 以准确显示我是如何设置的
  • 拜托,jest.mock('axios', () => ({ get: jest.fn().mockReturnValue(Promise.reject('error')) })); - 正如我所说,在describe 部分之前执行此操作
  • 还有await expect(API.get(GROUPS.url()).rejects.toEqual('error');——应该是这样的
  • 试过了,但没有任何改变。我
  • 同样的错误,Received has type: function Received has value: [Function anonymous]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-25
  • 2015-06-04
  • 1970-01-01
  • 2017-07-16
  • 2018-11-22
相关资源
最近更新 更多