Как мне протестировать функцию, которая вызывает другую функцию в шутку?

#javascript #jestjs

#javascript #jestjs

Вопрос:

У меня есть функция, которая преобразует массив из 8-битных целых чисел в x-битное целое число. Эта функция имеет обширные модульные тесты в шутку. Эта функция вызывается convertArrayIntoInt() .

У меня есть другие функции, которые зависят от convertArrayIntoInt() called getSignature() .

 /**
 * @param {Uint8Array} fileContents The file contents
 * @param {number} position The position in the file where the signature is.
 * @return {number} the 32 bit signature
 */
function getSignature(fileContents, position) {
    let signature = fileContents.slice(position, position   4);
    signature = convertArrayIntoInt(signature);
    for(let s in Enums.Signatures) {
        if(signature === parseInt(s)) {
            return signature;
        }
    }
    return Enums.Signatures.BAD_SIGNATURE;
}
  

Я хочу написать тест для этой функции, который проверяет, Uint8Array.of(0x04, 0x03, 0x4b, 0x50), 0) возвращает 0x04034b50 или Enums.BAD_SIGNATURE . Я слышал, что при модульном тестировании вы не хотите тестировать функцию, которая полагается на выходные данные другой функции. Как мне сделать это в шутку?

Ответ №1:

Обновление: Похоже, у меня была какая-то проблема в моем первоначальном ответе, когда я объединил разные файлы в один файл, я ожидал, что он будет работать как раньше, но этого не произошло, поэтому обязательно поместите функции, которые вы хотите внедрить, в отдельные файлы.

Как упоминалось ранее, модульный тест должен просто проверять функциональность самой функции, одновременно имитируя зависимости.

Я переместил функции в отдельные файлы, в одном файле определены все функции, а в другом — тест.

enums.js

 export const Enums = {
  Signatures: {
    SIGNATURE_1: 1,
    SIGNATURE_2: 2,
    SIGNATURE_3: 3,
    BAD_SIGNATURE: -1
  }
};
  

convertArrayIntoInt.js

 export function convertArrayIntoInt(array) {
  // processing...
  return array.length;
}
  

getSignature.js

 import { convertArrayIntoInt } from "./convertArrayIntoInt";
import { Enums } from "./enums";

export const getSignature = (fileContents, position) => {
  let signature = convertArrayIntoInt(
    fileContents.slice(position, position   4)
  );

  for (let s in Enums.Signatures) {
    if (signature === parseInt(s, 10)) {
      return signature;
    }
  }

  return signature;
};
  

tests.spec.js

 import { getSignature } from "./getSignature";
import { Enums } from "./enums";
import * as convertArrayIntoIntModule from "./convertArrayIntoInt";

it("Function check", () => {
  // arrange
  const spy = jest.spyOn(convertArrayIntoIntModule, "convertArrayIntoInt");
  spy.mockReturnValue(Enums.Signatures.SIGNATURE_1);

  // act
  const expected = Enums.Signatures.SIGNATURE_1;
  const actual = getSignature([1, 2, 3, 4, 5, 6], 1);

  // assert
  expect(spy).toBeCalledTimes(1);
  expect(actual).toEqual(expected);

  // clean up
  spy.mockRestore();
});
  

Вы можете взглянуть на эту песочницу, которую я создал для тестирования фиктивной функции, похожей на вашу.

Комментарии:

1. Похоже, что это на самом деле не работает. codesandbox.io/s /… — Если я имитирую возвращаемое значение фактической подписи и ожидаю, что эта фактическая подпись будет возвращена, тест завершится неудачей.

2. Вот еще одна песочница, показывающая, что издевательский возврат никогда не вызывается codesandbox.io/s /…

3. @Cygnini-ShadowRi5ing обновил мой ответ, я объединил рабочий код из отдельных файлов в один, и это была проблема с codesandbox. Взгляните на обновленные ссылки и пример.

Ответ №2:

Да, вы правильно расслышали. Модульный тест должен тестировать только один модуль / функцию. Что вы можете сделать, так это выполнить другой модульный тест для проверки функции convertArrayIntoInt (), и для этой функции вы можете установить фиктивные возвращаемые значения для convertArrayIntoInt (), чтобы проверить, правильно работает другая логика или нет.

Комментарии:

1. Это то, о чем я думал, но с Jest, какой самый простой способ сделать это?

2. tbh У меня нет никакого опыта работы с Jest. Но я думаю, что это было бы полезно jestjs.io/docs/en/mock-functions.html

3. Я не уверен, как заставить это работать в этом контексте.

Ответ №3:

Вы можете использовать функцию convertarrayintointи mockReturnValue. https://jestjs.io/docs/en/jest-object#jestspyonobject-methodname

Комментарии:

1. Я не смог заставить это работать. Если вы знаете, как заставить это работать, предоставьте пример кода.