2016-11-09 17 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

相关问题