![](/img/trans.png)
[英]AngularJS : testing a factory that returns a promise, while mocking a service that uses $http
[英]AngularJS - Testing service method that uses $http service
我的服务功能看起来像这样:
addStatement: function(user, action, object) {
var statement = {
user: user,
action: action,
object: object
};
$http({
method: 'POST',
url: '/foo/bar',
data: statement,
headers: {Authorization: 'Basic YWxhZGRpbjpvcGVuIHNlc2FtZQ=='}
}).success(function(data) {
alert("success: " + data);
});
}
我想为这个方法编写单元测试,但我不确定如何使它工作。 基本上,我想测试发送的数据是否已从函数参数中正确构造,并且发送了正确的Authorization标头。
我一直在阅读如何使用$ httpBackend ,但是那里的例子是测试一个控制器,只是在发出请求并返回时在$ scope上发生了变化。 有没有办法实现我想要的测试? 或者我说错了什么?
测试服务与测试控制器没有太大差别,因此原理是相同的。 基本上你需要:
如果您在测试服务方法导致$ http POST调用后,您可以像这样编写测试(省略非必要部分):
beforeEach(module('MyApp'));
beforeEach(inject(function(MyService, _$httpBackend_) {
service = MyService;
$httpBackend = _$httpBackend_; // angular strips the underscores so
// we don't need to use unique names
// https://docs.angularjs.org/api/ngMock/function/angular.mock.inject
}));
it('should invoke service with right paramaeters', function() {
$httpBackend.expectPOST('/foo/bar', {
"user": "testUser",
"action": "testAction",
"object": {}
}, function(headers){
return headers.Authorization === 'Basic YWxhZGRpbjpvcGVuIHNlc2FtZQ==';
}).respond({});
service.addStatement('testUser', 'testAction', {});
$httpBackend.flush();
});
以下是工作中的jsFiddle,说明了这个测试的实际效果: http : //jsfiddle.net/pkozlowski_opensource/MkrjZ/2/
最后一句话:最好不要在单元测试中使用.alert(),因为这些警报会暂停执行测试。
我写了一篇关于这个主题的博客文章,展示了使用angular的内置模拟和编写自己的模拟的一些内容,也许它可以帮助你更深入地理解:
简而言之,它定义了第二个用于测试的模块,可以模拟所需的行为:
var apptastic = angular.module('apptastic', []),
apptasticMock = angular.module('apptasticMock', []);
并覆盖原始行为,例如:
apptasticMock.service("socket", function($rootScope){
... // overwrite
});
然后它必须在测试中加载 - 这是有效的,因为角度按照加载的顺序覆盖已经定义的服务:
describe("Socket Service", function(){
var socket;
beforeEach(function(){
module('apptastic');
module('apptasticMock');
inject(function($injector) {
socket = $injector.get('socket');
});
});
it("tests something", function(){
... // test
});
});
有了良好的代码结构,即使继承也不是真正的问题,同时能够对应该被模拟的内容进行细粒度控制,以及应该从原始代码中使用什么。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.