我具有以下功能:
/**
* filters array down to the given allowed keys
* @param {Object} data
* @param {String[]} allowedKeys
*/
$scope.filterData = function(data, allowedKeys) {
return Object.keys(data)
.filter(function(key) {
return allowedKeys.includes(key);
})
.reduce(function(obj, key) {
obj[key] = data[key];
return obj;
}, {});
};
我要为其创建单元测试的到目前为止,我具有以下内容:
describe('$scope.filterData', function() {
//params
var data = {
key1: "value1",
key2: "value2",
key3: "value3"
}
var allowedKeys = ["key1", "key2"];
//mockobject
var $Object = jasmine.createSpyObj('Object', ['keys', 'filter', 'reduce']);
it('should func', function() {
$Object.keys.and.returnValue($Object);
$Object.filter.and.returnValue($Object);
$Object.reduce.and.returnValue($Object);
$scope.filterData(data, allowedKeys);
expect(Object.filter).toHaveBeenCalled();
});
});
我遇到的问题是出现以下错误:
TypeError:未定义不是构造函数(正在评估'allowedKeys.includes(key)')
我不明白,如何解决该错误?
答案 0 :(得分:0)
我不知道这种解决方案是否可以帮助您
在编写测试用例时,尤其是对功能进行测试时,我们倾向于测试功能的输入和输出值。
对我来说,我认为我们不应该通过调用茉莉花模拟来触及Array, Object
的原始功能。
如果您想知道函数在这种情况下是否正常运行。
例如:
describe('$scope.filterData', function() {
//params
var data = {
key1: "value1",
key2: "value2",
key3: "value3"
}
var allowedKeys = ["key1", "key2"];
it('should return 2 key', function() {
var expected = {
key1: "value1",
key2: "value2",
}
var value = $scope.filterData(data, allowedKeys);
expect(JSON.stringify(value)).toEqual(JSON.stringify());
});
});
当然,有时我们必须模拟一些函数,例如当我们有http请求并且必须等待时,或者我们有其他地方的函数要使用并且想要模拟它们。
但是在这种情况下,您的功能对于expect
某些功能to be called
并不是真正必需的,它足够简单,并且不依赖任何其他内容。
因此,最好只关注输入内容和功能的输出值
答案 1 :(得分:0)
首先,Object
没有函数filter
,而您的jasmine.createSpyObj
实际上是无用的。正如@Luan Phan在回答中所说,我们通常倾向于测试该函数的输入和输出值。无需在我们的测试中对Javascript内置函数进行测试。
但是,例如,如果您想知道是否在函数内部调用了Object.keys
,则为示例
it('should func', function () {
spyOn(Object, 'keys').and.callThrough();
$scope.filterData(data, allowedKeys);
expect(Object.keys).toHaveBeenCalled();
});
对于filterData
it('should func', function () {
spyOn(Object, 'keys').and.callThrough();
spyOn(Array.prototype, 'filter').and.callThrough();
spyOn(Array.prototype, 'reduce').and.callThrough();
$scope.filterData(data, allowedKeys);
expect(Object.keys).toHaveBeenCalled();
expect(Array.prototype.filter).toHaveBeenCalled();
expect(Array.prototype.reduce).toHaveBeenCalled();
});
如果您真的需要 mock 内置函数之一返回的内容,请参考以下示例
it('should func', function () {
const mockResult = {};
spyOn(Array.prototype, 'reduce').and.returnValue(mockResult);
const result = filterData(data, allowedKeys);
expect(result).toBe(mockResult);
});
同样,Javascript的内置函数已经在其他地方编写了测试,我们不需要在测试中对其进行测试,我们的重点应该放在编写的函数上。
>希望有帮助