Проверка кода функции в виде теста очень хрупкий и легко ломается, давая вам ложный отрицательный результат:
let someFn = function(a, b) {
return a + b;
}
let expected = `function(a, b) {
return a + b;
}`
console.log("Test original implementation:", test(someFn.toString(), expected));
//later the code style is changed to remove extra whitespace and make it one line
someFn = function(a, b) { return a+b; }
console.log("Test updated implementation:", test(someFn.toString(), expected));
//simple testing
function test(expected, actual) {
return expected == actual
}
Простое внесение нефункциональных изменений в код нарушает тест.
Еще хуже, если являются функциональными изменениями в коде, тест не может гарантировать, что новая реализация ведет себя так же, как и старая, поскольку она смотрит только на структуру кода:
//simplified case of what the actual code could be doing
function someCodeBaseFunction() {
let someInput = [8, 12, 42];
return someFn(...someInput)
}
let someFn = function(a, b) { return a+b; }
let expected = `function(a, b) { return a+b; }`
console.log("Test original implementation:", test(someFn.toString(), expected));
console.log("Codebase usage:", someCodeBaseFunction()); //20, as the third number is ignored
//new implementation
someFn = function(...args) {
return args.reduce((a, b) => a + b);
}
//update the test, so it passes
expected = `function(...args) {
return args.reduce((a, b) => a + b);
}`
console.log("Test updated implementation:", test(someFn.toString(), expected));
//some existing line of code
console.log("Codebase usage:", someCodeBaseFunction()); //62, as the third number is now used
//simple testing
function test(expected, actual) {
return expected == actual
};
Вместо этого, то, что вы хотите сделать, это проверить поведение кода и установить ваши ожидания там. Таким образом, если реализация изменится, вы сможете убедиться, что реализация по-прежнему соответствует тому же набору ожиданий.
В этом случае вам нужно создать пример ввода, который изначально неупорядочен, попробуйте упорядочить его, а затем ожидать, что порядок работал так, как вы ожидали. В псевдокоде это будет выглядеть примерно так:
//arrange
input = [
{testProperty: "c", id: 1},
{testProperty: "a", id: 2},
{testProperty: "d", id: 3},
{testProperty: "b", id: 4}
];
expected = [
{testProperty: "a", id: 2},
{testProperty: "b", id: 4},
{testProperty: "c", id: 1},
{testProperty: "d", id: 3}
];
//act
input.sort(component.getComparisonFunction('testProperty'))
//assert
expect(input).toEqual(expected);
Вы также можете добавить больше тестов на более детальном уровне, чтобы связать ожидания еще больше, если хотите. Например, если вы хотите убедиться, что сравнение чувствительно к регистру
//arrange
a = { testProperty: "a" };
b = { testProperty: "B" };
//act
result = component.getComparisonFunction('testProperty')(a, b)
//assert
expect(result).toBeGreaterThanOrEqual(1)
Или без учета регистра:
//arrange
a = { testProperty: "a" };
b = { testProperty: "B" };
//act
result = component.getComparisonFunction('testProperty')(a, b)
//assert
expect(result).toBeLessThanOrEqual(-1)
Это определяет ваши ожидания гораздо более четко и гарантирует, что будущие изменения покроют именно то, что вам нужно.