#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. Я не смог заставить это работать. Если вы знаете, как заставить это работать, предоставьте пример кода.