简体   繁体   English

如何在解决承诺之前正确地让 jest axios 模拟等待

[英]How to properly have jest axios mock wait before resolving promise

I have a function like this:我有一个这样的功能:

join(): void {
    this.working.value = true;
    if (this.info.value) {
      axios.get('/url')
        .then((result: ResultStatus) => {
          this.result = result;
        })
        .catch((reason: AxiosError) => {
          this.showError(AjaxParseError(reason));
        })
        .finally(() => {
          this.working.value = false;
        });
    }
  }

and I want to write some unit tests for this.我想为此编写一些单元测试。 The first unit test I want to write is to test that 'this.saving' is set to true so that I ensure my UI has a value it can use to show a loading indicator.我要编写的第一个单元测试是测试 'this. Saving' 是否设置为 true,以便确保我的 UI 具有可用于显示加载指示器的值。

However, when I use jest to mock axios, jest resolves the axios promise immediately and I don't have a chance to test what happens before the then/finally block is called.但是,当我使用 jest 模拟 axios 时,jest 会立即解决 axios 承诺,并且我没有机会测试在调用 then/finally 块之前会发生什么。 Here is what my unit test code looks like:这是我的单元测试代码的样子:

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

import successResponse from './__json__/LeagueJoinInfoSuccess.json';

describe('constructor:', () => {
    let vm: classUnderTest;
    beforeEach(() => {
      vm = new classUnderTest();
      mockedAxios.get.mockResolvedValue({ data: successResponse }); // set up the response
      vm.join(); // the function under test
    });
    it('should set working true before calling the server to join', () => {
      expect(vm.working.value).toBeTruthy();
    });
    it('should set working false after calling the server responds', async () => {
      await flushPromises();
      expect(vm.working.value).toBeFalsy();
    });
});

The first expect statement is always false because the finally block is run before I have a chance to do an await flushPromises();第一个expect语句总是错误的,因为finally块在我有机会执行await flushPromises()之前就运行了; so the working value is always false.所以工作值总是假的。

Is there a convenient way to get jest's mock of axios to wait before resolving its promise?有没有一种方便的方法可以让 jest 的 axios 模拟在解决其承诺之前等待?

UPDATE: Now here is a really strange thing: If I move the contents of BeforeEach into each of the tests, then it behaves the way that I am hoping it would behave.更新:现在有一件非常奇怪的事情:如果我将 BeforeEach 的内容移动到每个测试中,那么它的行为方式就会像我希望的那样。 I guess I will open an issue over at jest and ask them what's going on.我想我会开玩笑地打开一个问题并询问他们发生了什么。

I have a solution for you to create a promise as response, however, we're not gonna resolve it in the 1st test case to keep you test loading state then resolve it in the 2nd test as following:我有一个解决方案供您创建承诺作为响应,但是,我们不会在第一个测试用例中解决它以保持您测试加载状态,然后在第二个测试中解决它,如下所示:

describe('constructor:', () => {

  let vm: classUnderTest;

  // Resolve function
  let resolveFn: (value?: unknown) => void

  beforeEach(() => {
    vm = new classUnderTest();

    const promise = new Promise(resolve => {
      // hold the resolve function to call in 2nd test
      resolveFn = resolve;
    });
    mockedAxios.get.mockImplementation(() => promise);

    vm.join(); // the function under test
  });

  it('should set working true before calling the server to join', () => {
    expect(vm.working.value).toBeTruthy();
  });

  it('should set working false after calling the server responds', async () => {
    // resolve the pending promise
    resolve({
      data: successResponse,
    });

    // I think you would wait the promise resolved
    await new Promise(resolve => setTimeout(resolve));

    expect(vm.working.value).toBeFalsy();
  });
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM