【问题标题】:Jasmine: how to test async function?Jasmine:如何测试异步功能?
【发布时间】:2021-01-18 05:32:17
【问题描述】:

在我的 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 毫秒内完成(设置 by jasmine.DEFAULT_TIMEOUT_INTERVAL)

我已将jasmine.DEFAULT_TIMEOUT_INTERVAL 增加到 20000 毫秒,但它仍然不起作用。 如何测试这样的异步函数?

我找到了一些 coupe 示例,但它们在我的情况下不起作用: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
  });

【问题讨论】:

  • 您的测试似乎需要超过 20 秒才能执行,它需要 10 秒来执行 await wait(TIMEOUT);,另外 10 秒来执行 jasmine.clock().tick(10000);。当你设置jasmine.DEFAULT_TIMEOUT_INTERVAL = 22000 时会发生什么?

标签: javascript node.js unit-testing jasmine


【解决方案1】:

问题在于,使用 jasmine 的自定义时钟,您需要手动调用 .tick() 以将时间向前移动。由于您立即等待wait 呼叫,因此将无法到达wait 中的setTimeout。因此,承诺永远不会解决,因为您在等待承诺后调用 .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);
    
  });

【讨论】:

  • 对不起eol,但像您提供的解决方案那样做没有任何意义 - 它不断抛出错误
  • 为什么没有意义? “它不断抛出错误” - 什么现在是错误?
  • wait不是spy,我改成spy后,并没有涵盖整个方法:(我已经更新了帖子
  • 嗯 wait 不是间谍正是我在回答的最后一句话中告诉你的。
  • 另外你创建的间谍不正确..我已经更新了我的答案来告诉你如何..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-29
  • 2019-11-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-03
  • 1970-01-01
相关资源
最近更新 更多