茉莉花:如何测试异步功能?

时间:2020-10-02 14:26:07

标签: javascript node.js unit-testing jasmine

在我的NodeJS应用中,我使用一种方法heplers.ts获得了以下wait文件:

export const wait = async (ms: number) => {
  return new Promise(resolve => {
    setTimeout(resolve, ms);
  });
};

我目前正在对此文件编写单元测试,这就是我现在所拥有的:

import { setProcessEnv } from 'spec/helpers';
import { wait } from '../../util/helpers';

describe('Helper methods', () => {
  beforeEach(() => {
    jasmine.DEFAULT_TIMEOUT_INTERVAL = 20000;
    setProcessEnv();
  });

  it('should wait a specified amount of time', async () => {
    const TIMEOUT = 10000;
    jasmine.clock().install();  // First install the clock

    await wait(TIMEOUT);

    jasmine.clock().tick(10000); // waits till 10000 milliseconds

    expect(wait).toHaveBeenCalled();
    
    jasmine.clock().uninstall(); // uninstall clock when done
  });
  
});

但是我一直在收到

错误:超时-异步功能未在20000毫秒内完成(设置 jasmine.DEFAULT_TIMEOUT_INTERVAL)

我已经将jasmine.DEFAULT_TIMEOUT_INTERVAL增加到了20000毫秒,但仍然无法正常工作。 如何测试这种异步功能?

我找到了政变实例,但在我的案例中却不起作用:How to test a function which has a setTimeout with jasmine?

更新

这是我的最新版本,不会引发错误,但问题是它不包含return语句行(return new Promise(...):

it('should wait a specified amount of time', async () => {
     const TIMEOUT = 10000;

    // jasmine.clock().install();  // First install the clock
    const wait = jasmine.createSpy();

    await wait(TIMEOUT);

    // jasmine.clock().tick(1000); // waits till 10000 milliseconds
    expect(wait).toHaveBeenCalled();
    expect(wait).toHaveBeenCalledWith(TIMEOUT);
    
    // jasmine.clock().uninstall(); // uninstall clock when done
  });

1 个答案:

答案 0 :(得分:2)

问题在于,使用茉莉花的自定义时钟,您需要手动调用.tick()来向前移动时间。由于您立即等待wait的呼叫,因此无法接通setTimeout中的wait。因此,如您在等待诺言后致电.tick(),诺言就永远无法解决。

您可以通过以下方法解决此问题:不立即等待wait返回的promise,而是将其分配给变量,然后将时间提前。然后,等待诺言并检查是否已调用wait

describe('Helper methods', () => {

    it('should wait a specified amount of time', async () => {
        const TIMEOUT = 10000;
        jasmine.clock().install();  // First install the clock

        const waitPromise =  wait(TIMEOUT);
        jasmine.clock().tick(10000); // waits till 10000 milliseconds

        await waitPromise; // now await the promise

        expect(wait).toHaveBeenCalled();

        jasmine.clock().uninstall(); // uninstall clock when done
    });
});

请注意,在以上代码中,wait上没有设置间谍程序,因此.toHaveBeenCalled可能会失败。如果需要帮助来设置某个功能的间谍,请检查以下链接:https://stackoverflow.com/a/43532075/3761628


要回答更新的问题:您错误地设置了间谍。您需要将其更改为:

import { setProcessEnv } from 'spec/helpers';
import * as WaitFunction from from '../../util/helpers';
...
it('should wait a specified amount of time', async () => {
    const TIMEOUT = 10000;    
    
    const waitSpy = spyOn(WaitFunction, 'wait').and.callThrough();

    await WaitFunction.wait(TIMEOUT);

    expect(waitSpy).toHaveBeenCalled();
    expect(waitSpy).toHaveBeenCalledWith(TIMEOUT);
    
  });