[英]How to unit test with Jasmine on multiple chained functions with returns?
我有以下功能:
/**
* 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:undefined不是構造函數(評估'allowedKeys.includes(key)')
我不明白,該如何解決該錯誤?
我不知道這種解決方案是否可以幫助您
當我們編寫測試用例,特別是對功能的測試時,我們傾向於測試功能的輸入和輸出值。
對我來說,我認為我們不應該通過調用茉莉花模擬來接觸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
某個函數,它就足夠了,並且不依賴任何其他函數。
所以最好只關注函數的輸入和輸出值
首先, 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();
});
如果您真的需要模擬其中一個內置函數返回的內容,請參考以下示例
it('should func', function () {
const mockResult = {};
spyOn(Array.prototype, 'reduce').and.returnValue(mockResult);
const result = filterData(data, allowedKeys);
expect(result).toBe(mockResult);
});
同樣,Javascript的內置函數已經在其他地方編寫了測試,我們不需要在測試中對其進行測試,我們的重點應該放在編寫的函數上。
希望能幫助到你
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.