我有一个返回 ComparisonFunction 的函数
getComparisonFunction(propertyOfComparison) {
const func = function(a, b){
if ( a[propertyOfComparison] < b[propertyOfComparison] ) {
return -1;
}
if ( a[propertyOfComparison] > b[propertyOfComparison] ) {
return 1;
}
return 0;
};
return func;
}
此方法将在 javascript“排序”方法中使用。 例如:
arrayOfObjects.sort(getComparisonFunction('name'));
此方法将按“name”属性对“arrayOfObjects”进行排序。 方法工作正常,问题是: 我如何比较具有不同参数的函数调用
it('should get correct comparison function', function () {
const func = component.getComparisonFunction('testProperty');
const expectedFunc = function(a, b){
if ( a['testProperty'] < b['testProperty'] ) {
return -1;
}
if ( a['testProperty'] > b['testProperty'] ) {
return 1;
}
return 0;
};
expect(func.toString()).toEqual(expectedFunc.toString());
});
这就是我现在拥有的,但它不起作用。运行代码后收到的错误是:
Expected 'function (a, b) {
if (a[propertyOfComparison] < b[propertyOfComparison]) {
return -1;
}
if (a[propertyOfComparison] > b[propertyOfComparison]) {
return 1;
}
return 0;
}' to equal 'function (a, b) {
if (a['testProperty'] < b['testProperty']) {
return -1;
}
if (a['testProperty'] > b['testProperty']) {
return 1;
}
return 0;
}'.
最佳答案
检查函数的代码作为测试非常很脆弱,很容易破坏,给你一个假阴性:
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
};
相反,您想要执行的操作是测试代码的行为并在那里设定您的期望。这样,如果实现发生变化,您可以确保实现仍然符契约(Contract)一组期望。
在这种情况下,您需要创建一个最初无序的示例输入,尝试对其进行排序,然后期望该顺序按您的预期工作。在伪代码中,它看起来有点像这样:
//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)
这更清楚地定义了您的期望,并确保 future 的更改将准确满足您的需求。
关于javascript - 如何在javascript中测试两个具有不同参数值的返回函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56805478/