2016-11-09 78 views
1

我有一個Angular1控制器調用一個返回promise的Service。當向控制器調用服務時添加.catch()方法時,mocha會引發以下錯誤。測試包含.catch()方法的Promise時出錯

TypeError: undefined is not an object (evaluating 'DogService.getDogs(_this.userId) 
      .then(function(result){ 
       _this.myDogs = result; 
      }) 
      .catch') in app/scripts/controllers/main.js (line 20) 
    [email protected]/scripts/controllers/main.js:20:11 
    test/spec/controllers/main.js:33:20 
    [email protected]://localhost:8080/context.js:151:17 

控制器

angular.module('testProblemApp').controller('MainCtrl', ['DogService', function (DogService) { 
var _this = this; 
_this.myDogs = []; 
_this.userId = 1; 

_this.init = function(){ 
    DogService.getDogs(_this.userId) 
    .then(function(result){ 
     _this.myDogs = result; 
    }) 
    .catch(function(error){ 
     console.log(error); 
    }); 
}; 
}]); 

測試

describe('initialze function', function() { 
it('should set the myDogs array to the value returned by the Service', function() { 
    spyOn(DogService, 'getDogs').and.callFake(function() { 
    return { 
     then: function (callback) { 
     return callback([{ id: 1, name: 'baxter' }]); 
     }, 
     catch: function(callback){ 
     return callback('Error'); 
     } 
    } 
    }); 
    MainCtrl.init(); 
    expect(MainCtrl.myDogs).toEqual([{ id: 1, name: 'baxter' }]); 
}); 
}); 

如果刪除從測試通過控制器的.catch()

回答

1

這裏的問題是鏈接。預計then將返回一個具有catch方法的承諾對象。而thengetDogs模擬回報undefined

使用從頭開始編寫的自定義存根來模擬承諾或其他核心功能是不方便的。 $q承諾可以$q承諾進行測試:

var dogsPromiseMock; 
... 
spyOn(DogService, 'getDogs').and.callFake(function() { 
    return dogsPromiseMock; 
}); 
... 
dogsPromiseMock = $q.resolve([{ id: 1, name: 'baxter' }]); 
MainCtrl.init(); 
$rootScope.$digest(); 
expect(MainCtrl.myDogs).toEqual(...); 
... 
dogsPromiseMock = $q.reject(); 
MainCtrl.init(); 
$rootScope.$digest(); 
expect(MainCtrl.myDogs).toEqual(...); 

作爲一個經驗法則,最好是檢查控制單元,而不僅僅是單一的模擬方法時,要充分模擬服務。

+0

感謝您的幫助! – Reustonium

+0

不客氣。 – estus

相關問題