Как проверить, ожидали ли функцию, а не только вызывали? - PullRequest
0 голосов
/ 16 мая 2019

Попробуйте проверить следующую упрощенную функцию

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

В моем шутливом тесте я хочу убедиться, что otherModule.otherFunction не только вызывается, но и ожидает. Другими словами, я хочу написать тест, который не будет выполнен, если кто-то удалит await перед вызовом otherFunction.

У меня пока что это

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

Но проверка expect(otherModule.otherFunction).toHaveBeenCalledWith(3); не подтверждает, что functionToBeTested ожидал otherFunction.

Ответы [ 2 ]

1 голос
/ 16 мая 2019

Вот что я придумал:

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();
}

Итак, я высмеиваю другую функцию, чтобы вернуть обещание, которое начинается нерешенным, но я могу решить его по своему усмотрению во время теста.Затем я вызываю функцию, которую хочу протестировать, и вызываю ее, когда она завершится.

Затем я хочу заявить, что он не вызывал обратный вызов, но, поскольку разрешение обещания всегда асинхронно, мне нужно добавить тайм-аут 0, чтобы дать обещанию шанс разрешить.Я решил сделать это с заданной в обещании версией setTimeout.

И, наконец, я разрешаю mockPromise, делаю тайм-аут 0 (снова, чтобы убедиться, что обещание получит возможность вызывать его обратные вызовы), иутверждают, что теперь разрешение было вызвано .

0 голосов
/ 19 мая 2019

Если вы не можете проверить по otherModule.otherFunction разрешенному значению или по каким-либо побочным эффектам, нет необходимости проверять, разрешается ли оно.

В противном случае удаление await в следующих примерах приведет к сбою тестов.

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);
    });
});

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 ***');
    });
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...