根据针对ngMock的Angular文档,$ httpBackend方法应该拦截$ http服务请求并提供指定的响应。我假设模拟$ httpBackend方法将是同步的,以使测试更容易。但是result.test最终没有被定义。
describe('Http requests', function () {
var scope, $httpBackend, constituents;
beforeEach(module('main'));
beforeEach(inject(function (_$httpBackend_, _constituents_) {
constituents = _constituents_;
$httpBackend = _$httpBackend_;
$httpBackend.expectGET("App/Main/login.html").respond(200);
}));
it('Should get the constituents', function () {
$httpBackend.whenGET(webServicesPath + "api/constituents/all-constituents").respond(200, { "test": true });
var result = constituents.getAllConstituents();
$httpBackend.flush();
expect(result.$$state.value.test).toEqual(true);
});
});
我尝试使用$ httpBackend.flush(),但这会产生意想不到的后果......
错误:意外请求:GET App / Main / login.html
这意味着以某种方式调用了ui.routing服务。所以我通过在$httpBackend.expectGET...
中添加beforeEach
来处理这个问题。
为什么我甚至不得不使用flush方法?看起来过于复杂。当它与我的单元测试无关时,为什么会触发ui.routing?
作为参考,这是工厂使用的
app.factory('constituents', ['$http', '$log', function ($http, $log) {
function getAllConstituents() {
return $http.get(webServicesPath + "api/constituents/all-constituents").then(
function (response) {
return response.data;
},
function (response) {
$log.error("Load Constituents - " + response.status + " " + response.statusText);
return;
}
);
}
return {
getAllConstituents: getAllConstituents
}
}]);
答案 0 :(得分:5)
您的results
变量是承诺,而不是$http
请求的结果。您必须执行以下操作才能访问结果:
it('Should get the constituents', function () {
var result;
$httpBackend.whenGET('foo.json').respond(200, { "test": true });
constituents
.getAllConstituents()
.then(function(response){
result = response;
});
$httpBackend.flush();
expect(result.test).toEqual(true);
});
我的问题是为什么我甚至不得不使用flush方法?
因为编写异步单元测试可能很糟糕。因此,我们需要使用flush方法使我们的异步测试同步,这使得生活变得更加容易,因为我们不再需要创建假承诺的负载,并找出告诉我们的测试框架的done()
回调的位置测试结束等等。
为什么当它与我的无关时触发ui.routing 单元测试?
您可以在此SO问题中阅读更多相关信息
UI-router interfers with $httpbackend unit test, angular js
这可能很痛苦,但我发现使用像bardJS这样的帮助程序库可能是让ui-router
问题消失的最快方法,它也删除了很多样板文件您需要为Angular单元测试编写。