Javascript 如何测试函数是否被等待,而不是仅被调用?

Javascript 如何测试函数是否被等待,而不是仅被调用?,javascript,jestjs,Javascript,Jestjs,考虑测试以下简化函数 const functionToBeTested = async (val) => { await otherModule.otherFunction(val/2); } 在我的jest测试中,我想确保otherModule.otherFunction不仅被调用,而且被等待。换句话说,我想编写一个测试,如果有人从otherFunction调用前面删除wait,该测试将失败 到目前为止,我已经完成了这项工作 test('should wait on other

考虑测试以下简化函数

const functionToBeTested = async (val) => {
    await otherModule.otherFunction(val/2);
}
在我的jest测试中,我想确保
otherModule.otherFunction
不仅被调用,而且被等待。换句话说,我想编写一个测试,如果有人从
otherFunction
调用前面删除
wait
,该测试将失败

到目前为止,我已经完成了这项工作

test('should wait on otherFunction', () => {
   await functionToBeTested(6) 
   expect(otherModule.otherFunction).toHaveBeenCalledWith(3);  
}

但是
expect(otherModule.otherFunction.)。已被(3)调用检查不会验证
要测试的功能是否已等待
其他功能

以下是我的想法:

const delay = duration => new Promise(resolve => setTimeout(resolve, duration));

test('should wait on otherFunction', async () => {
  let resolve;
  const mockPromise = new Promise((res) => {resolve = res;});
  otherModule.otherFunction.mockReturnValue(mockPromise);
  const resolution = jest.fn();

  functionToBeTested(6).then(resolution);

  expect(otherModule.otherFunction).toHaveBeenCalledWith(3);
  await delay(0);
  expect(resolution).not.toHaveBeenCalled();
  resolve();
  await delay(0);
  expect(resolution).toHaveBeenCalled();
}
因此,我模仿otherFunction返回一个未解决的承诺,但我可以在测试期间随意解决它。然后我调用我想要测试的函数,并在它完成时给它一个回调

然后我想声明它没有调用回调,但是由于承诺解析始终是异步的,所以我需要添加一个超时0,以给承诺一个解析的机会。我选择使用setTimeout的Promified版本来实现这一点


最后,我解析mockPromise,执行超时0(再次,确保promise有机会调用其回调),并断言现在已调用解析。

如果无法对照
otherModule.otherFunction
解析值或任何副作用进行检查,则无需测试它是否解析

否则,在以下示例中删除
wait
,将导致测试失败

describe('check for side effect', () => {
    let sideEffect = false;

    const otherModule = {
        otherFunction: x =>
            new Promise(resolve => {
                setTimeout(() => {
                    sideEffect = true;
                    resolve();
                }, 0);
            }),
    };

    const functionToBeTested = async val => {
        await otherModule.otherFunction(val / 2);
    };

    test('should wait on otherFunction', async () => {
        const spy = jest.spyOn(otherModule, 'otherFunction');

        await expect(functionToBeTested(6)).resolves.toBeUndefined();
        expect(spy).toHaveBeenCalledWith(3);
        expect(sideEffect).toBe(true);
    });
});


您是否可以检查第一个值是否与调用第二个函数时的值不符,然后在调用第二个函数后再次检查它?暗示不测试它是否完成,它是实现细节,或者您有一个具体的用例?对于
Mocha
Sinon
…相同的概念适用于使用
Jest
describe('check returned value', () => {
    const otherModule = {
        otherFunction: x =>
            new Promise(resolve => {
                setTimeout(() => {
                    resolve('hello');
                }, 0);
            }),
    };

    const functionToBeTested = async val => {
        const res = await otherModule.otherFunction(val / 2);
        return `*** ${res} ***`;
    };

    test('should wait on otherFunction', async () => {
        const spy = jest.spyOn(otherModule, 'otherFunction');

        const promise = functionToBeTested(6);
        expect(spy).toHaveBeenCalledWith(3);
        await expect(promise).resolves.toBe('*** hello ***');
    });
});