Jasmine:如何测试异步函数?
Jasmine: how to test async function?
在我的 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
});
});
但我不断收到
Error: Timeout - Async function did not complete within 20000ms (set
by 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
});
问题在于,使用jasmine 的自定义时钟,您需要手动调用.tick()
来将时间向前移动。由于您立即等待 wait
调用,因此 wait
内的 setTimeout
将无法到达。因此,当您在等待承诺后调用 .tick()
时,承诺永远不会解决。
您可以通过不立即等待从 wait
返回的承诺来解决此问题,而是将其分配给变量然后提前时间。然后,等待承诺并检查 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
可能会失败。如果您需要帮助设置一个函数的间谍,请检查此 link:
回答更新后的问题:您错误地设置了间谍。您需要将其更改为:
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);
});
在我的 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
});
});
但我不断收到
Error: Timeout - Async function did not complete within 20000ms (set by 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
});
问题在于,使用jasmine 的自定义时钟,您需要手动调用.tick()
来将时间向前移动。由于您立即等待 wait
调用,因此 wait
内的 setTimeout
将无法到达。因此,当您在等待承诺后调用 .tick()
时,承诺永远不会解决。
您可以通过不立即等待从 wait
返回的承诺来解决此问题,而是将其分配给变量然后提前时间。然后,等待承诺并检查 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
可能会失败。如果您需要帮助设置一个函数的间谍,请检查此 link:
回答更新后的问题:您错误地设置了间谍。您需要将其更改为:
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);
});