Angularjs 角度单元试验.相同服务中的模拟方法/闭包
我目前正在尝试使用单元测试我的angular service,但遇到了一个问题,希望有人能够解释为什么会发生这种情况。我重建了我目前的项目,以说明手头的问题 我还提供了一份 我有一项服务,Angularjs 角度单元试验.相同服务中的模拟方法/闭包,angularjs,unit-testing,sinon,Angularjs,Unit Testing,Sinon,我目前正在尝试使用单元测试我的angular service,但遇到了一个问题,希望有人能够解释为什么会发生这种情况。我重建了我目前的项目,以说明手头的问题 我还提供了一份 我有一项服务,peopleService: (function (){ angular.module('myApp') .factory('peopleService', peopleService); peopleService.$inject = ['$q']; function peo
peopleService
:
(function (){
angular.module('myApp')
.factory('peopleService', peopleService);
peopleService.$inject = ['$q'];
function peopleService ($q){
var people = ['Homer', 'Marge', 'Bart', 'Lisa', 'Maggie'];
// in actual project, this makes an http request
function getFamily () {
return people;
}
function getAdults (){
var family = getFamily();
return family.filter(function (person){
return person === 'Homer' || person === 'Marge';
});
}
return {
getFamily: getFamily,
getAdults: getAdults
}
}
}());
在这个服务中,我的方法使用getFamily
,过滤结果并返回数据
在我的单元测试中,我试图模拟getFamily
,看看是否调用了该方法。这就是问题所在
我尝试的第一件事是删除该方法并覆盖当前方法,如下所示:
beforeEach(function (){
module('myApp');
inject(function (_peopleService_){
peopleService = _peopleService_; // get the service
sinon.stub(peopleService, 'getFamily'); // stub it
});
});
然后,我去测试get成人
是否调用getFamily
方法:
it('getAdults should call "getFamily" once', function(){
peopleService.getAdults();
expect(peopleService.getFamily.calledOnce).toBe(true);
});
测试失败,未调用存根方法
我调试并发现,尽管函数实际上已更改:
服务仍然保留对创建服务时使用的方法的引用(闭包):
我最初的想法是我没有正确地使用这个方法。然后,我尝试使用($provide.value
)覆盖该方法,最后得到了相同的结果(闭包保留在原始方法上)
解决方法是使用此:
function getAdults (){
var family = this.getFamily(); // <-- by using this.getFamily would reference the mock
return family.filter(function (person){
return person === 'Homer' || person === 'Marge';
});
}
函数{
var family=this.getFamily();//在对象上存根方法时,将覆盖该对象的属性,而不是它引用的原始函数
以以下代码为例:
function myFunction () {};
var myObj = { prop: myFunction };
myObj.prop === myFunction; // true
myObj.prop = 'changed';
typeof myFunction === 'function'; // true
myObj.prop === myFunction; // false
更改myObj.prop
并没有更改原始函数,myFunction
本身仍然存在。myObj.prop
但是,它失去了对myFunction
的引用。如果这是在sinon世界中,stubing只是将myObj.prop
的引用更改为存根对象
这就是为什么在调用同一服务中的另一个函数的服务中测试代码时,该代码需要引用该服务返回的同一对象。如果要避免在任何地方使用This
关键字,可以这样构造服务:
angular.module('myApp')
.factory('peopleService', peopleService);
peopleService.$inject = ['$q'];
function peopleService ($q){
var service = {
getFamily: getFamily,
getAdults: getAdults
};
return service;
function getFamily () {
// ...
}
function getAdults (){
var family = service.getFamily(); // <-- reference service.getFamily()
// ...
}
}
angular.module('myApp')
.工厂(“peopleService”,peopleService);
peopleService.$inject=['$q'];
功能peopleService($q){
var服务={
getFamily:getFamily,
Get成人:Get成人
};
回程服务;
函数getFamily(){
// ...
}
函数(0){
var family=service.getFamily();//看来您的plunker已经不可用了。我认为这个答案应该得到奖励,它非常清晰和完整