Javascript 如何监视服务来测试它——AngularJS/Jasmine
我尝试了我在互联网上找到的一切,但都没有成功。试图在我的服务中测试功能,但根据我的覆盖范围,我从未访问过它。任何帮助都将不胜感激:) 服务:Javascript 如何监视服务来测试它——AngularJS/Jasmine,javascript,angularjs,unit-testing,jasmine,code-coverage,Javascript,Angularjs,Unit Testing,Jasmine,Code Coverage,我尝试了我在互联网上找到的一切,但都没有成功。试图在我的服务中测试功能,但根据我的覆盖范围,我从未访问过它。任何帮助都将不胜感激:) 服务: 'use strict'; angular.module('Service').service('configService', function( $rootScope, $http) { var configObj = null; return { getConfig: function() { if (config
'use strict';
angular.module('Service').service('configService', function(
$rootScope, $http) {
var configObj = null;
return {
getConfig: function() {
if (configObj != null) {
console.log("returning cached config");
return configObj;
}
else {
return $http.get('conf.json').then(function(res) {
$http.get(res.confLocation).then(function(
locationResponse) {
configObj = locationResponse;
$rootScope.configObj = configObj;
console.log($rootScope.configObj);
return configObj;
});
});
}
}
};
});
在我尝试的测试中,从未访问过getConfig
服务测试:
'use strict';
describe('Service: configService', function() {
// load the controller's module
beforeEach(module('Service'));
var configService, $httpBackend, results, tstLocation, tstRes;
var tstConfig = {
"confLocation": "local-dev-conf.json"
};
var tstConfigEmpty = {};
var tstConfigObjEmpty = {};
var tstConfigObj = {
"AWS": {
"region": "us-east-1",
"endpoint": "http://localhost:8133"
}
};
// Initialize the controller and a mock scope
beforeEach(inject(function(_configService_, _$httpBackend_) {
inject(function($rootScope) {
$rootScope.USERNAME = 'TESTER';
$rootScope.configObj = tstConfigObj;
$rootScope.locationResponse = tstLocation;
$rootScope.res = tstRes;
});
configService = _configService_;
$httpBackend = _$httpBackend_;
//Problem here??
spyOn(configService, 'getConfig').and.callFake(function() {
return {
then: function() {
return "something";
}
};
});
}));
it('should return a promise', function() {
expect(configService.getConfig().then).toBeDefined();
});
it('should test backend stuff', inject(function() {
results = configService.getConfig(tstConfig);
$httpBackend.expectGET('conf.json').respond(tstConfig);
$httpBackend.expectGET('local-dev-conf.json').respond(tstConfigObj);
$httpBackend.flush();
}));
//Thanks Miles
it('should check if it was called', inject(function() {
results = configService.getConfig().then();
expect(configService.getConfig).toHaveBeenCalled();
});
// console.log(results);
}));
it('should check for a null configObj', inject(function() {
results = configService.getConfig(tstConfigObjEmpty).then(function() {
expect(results).toBe(null);
});
// console.log(results);
// console.log(tstConfigObj);
}));
it('should check for a non-null configObj', inject(function() {
results = configService.getConfig(tstConfigObj).then(function() {
// Any string is accepted right now -- Why??
expect(results).toEqual("returning cached config");
expect(results).toBe("returning cached config");
expect(results).toBe("your mom"); // SHOULDN'T BE WORKING BUT DOES
expect(results).toEqual("Object{AWS: Object{region: 'us-east-1', endpoint: 'http://localhost:8133'}}");
expect(results).toBe("Object{AWS: Object{region: 'us-east-1', endpoint: 'http://localhost:8133'}}");
});
// console.log(results);
// console.log(tstConfigObj);
}));
it('should check for null file', inject(function() {
results = configService.getConfig(tstConfigEmpty).then(function() {
expect(results).toEqual(null);
expect(results).toBe(null);
});
}));
it('should test a valid file', inject(function() {
results = configService.getConfig(tstConfig).then(function() {
expect(results).not.toBe(null);
expect(results).toEqual("Object{confLocation: 'local-dev-conf.json'}");
})
});
我认为我使用spyOn是错误的,或者在测试中没有正确访问getConfig。想法
编辑:
编辑2:由于Miles发现了一个问题,更改了测试3,但仍然没有更新测试覆盖率。正如艾米指出的,我的间谍逻辑出了问题。我不应该用电话,看起来是假的
编辑3:由于迈尔斯的帮助,现在可以访问该功能。必须将我的spyOn更改为:
spyOn(configService, 'getConfig').and.callThrough();
然后添加测试用例:
results = configService.getConfig(tstConfig).then();
expect(configService.getConfig).toHaveBeenCalled();
您使用的是哪种版本的茉莉花?Jasmine 2.0中添加了and.callFake语法。也许测试套件只需要指向新版本
您调用的是假函数,而不是函数。因此函数内部的逻辑不会被调用。这里有一个问题:
results = configService.getConfig(tstConfigObj).then(function() {
expect(results).toHaveBeenCalled();
expect(results).toHaveBeenCalledWith(tstConfigObj);
});
getConfig
不接受任何参数,也不接受then
。忽略这些错误,results
被分配了中的字符串“something”,然后
。即使expect
语句触发,您似乎也在测试是否调用了字符串。请尝试以下方法:
results = configService.getConfig().then();
expect(configService.getConfig).toHaveBeenCalled();
你能详细说明一下吗?我对Angular/Jasmine相当陌生,还不太了解spyOn。谢谢除非您需要测试某个函数是否已被调用,否则不要监视该函数(因此,您可能会在测试中监视此服务中的某个函数,以获取使用该函数的内容)。如果您需要监视它,并且需要运行其中的代码,请使用@Miles P在其评论中所说的
和.callThrough
。感谢您的回复。我实现了这个更改,虽然测试通过了,但它仍然没有提供getConfig的任何覆盖。。。我认为我的spyOn有问题,正如Amy在上面提到的,但我有点不确定如何解决这个问题代码>然后执行results=configService.getConfig(tstConfig).then()代码>和最后的expect(configService.getConfig).tohavebeencall()代码>成功了!它终于访问了这个函数,我的覆盖率达到了42%。是时候处理剩下的代码了,非常感谢!根据你发布的代码,我不确定这是胜利。仅仅测试函数是否被调用并不能给你带来任何好处。虽然这个答案在技术上是正确的,但它并不能帮助OP解决实际问题(不理解间谍的作用)。我没有投反对票,但这不是一个好答案,尽管被接受。我使用的是Jasmine 2.4.1。您是否尝试过and.returnValue而不是and.callFake并返回thenable?我尝试过用and.returnValue替换and.callFake,以及:“spyOn(配置服务,'getConfig')。和.returnValue(函数(){return{then:function(){return“something”;“当我这样做时,9个测试中的6个崩溃了。注意,在调用函数后的下一行中,不需要检查函数是否被调用了!