[英]How to unit test with Jasmine on multiple chained functions with returns?
I have the following function: 我有以下功能:
/**
* 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;
}, {});
};
that I want to create a unit test for and so far I have the following: 我要为其创建单元测试,到目前为止,我具有以下内容:
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();
});
});
The issue that I am having, is that I am getting the following error: 我遇到的问题是出现以下错误:
TypeError: undefined is not a constructor (evaluating 'allowedKeys.includes(key)')
TypeError:undefined不是构造函数(评估'allowedKeys.includes(key)')
I do not understand, how to fix that error? 我不明白,该如何解决该错误?
I don't if this solution could help you or not 我不知道这种解决方案是否可以帮助您
When we write test case, especially test for functions, we tend to test the input and output value for the function. 当我们编写测试用例,特别是对功能的测试时,我们倾向于测试功能的输入和输出值。
And for me, I think we shouldn't touch the primitive function of Array, Object
by calling jasmine mock. 对我来说,我认为我们不应该通过调用茉莉花模拟来接触
Array, Object
的原始功能。
If you want to know if your function is working properly in this case. 如果您想知道函数在这种情况下是否正常运行。
For example: 例如:
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());
});
});
Of course we have to mock some functions sometimes, like when we have the http request and have to wait, or we have function from other places to use and want to mock them. 当然,有时我们必须模拟某些功能,例如当我们有http请求并且必须等待时,或者我们有其他地方的功能要使用并且想要模拟它们。
But in this case, your function is not really necessary for expect
some function to be called
, it's simply enough and don't depend on anything else. 但是在这种情况下,您的函数并不是真正
expect
to be called
某个函数,它就足够了,并且不依赖任何其他函数。
So best we should only focus on the input and output values of function 所以最好只关注函数的输入和输出值
First of all, Object
does not have a function filter
and your jasmine.createSpyObj
is literally useless. 首先,
Object
没有函数filter
而您的jasmine.createSpyObj
实际上是无用的。 As @Luan Phan says in his answer, we usually tend to test the input and output value for the function. 正如@Luan Phan在回答中所说,我们通常倾向于测试该函数的输入和输出值。 Javascript built-in functions do not need to be tested in our tests.
Javascript内置函数无需在我们的测试中进行测试。
But, if you would like to know, for example, if Object.keys
was called inside your function, here is an example 但是,例如,如果您想知道是否在函数内部调用了
Object.keys
,则可以举一个例子
it('should func', function () {
spyOn(Object, 'keys').and.callThrough();
$scope.filterData(data, allowedKeys);
expect(Object.keys).toHaveBeenCalled();
});
The same can be done for the rest of the built-in functions used in filterData
对于
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();
});
If you really need to mock what one of the built-in functions returns, here is an example 如果您真的需要模拟其中一个内置函数返回的内容,请参考以下示例
it('should func', function () {
const mockResult = {};
spyOn(Array.prototype, 'reduce').and.returnValue(mockResult);
const result = filterData(data, allowedKeys);
expect(result).toBe(mockResult);
});
Again, Javascript's built-in functions already have tests written in some other place , we don't need to test it in our test, our focus should be on the functions we write. 同样,Javascript的内置函数已经在其他地方编写了测试,我们不需要在测试中对其进行测试,我们的重点应该放在编写的函数上。
Hope it helps 希望能帮助到你
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.