我一直在看这个好几个小时。我在例子后尝试了一些例子。我似乎无法让这个工作。请帮忙=)
我正在使用angular-seed repo(git://github.com/angular/angular-seed.git)的干净克隆进行所有这些操作。除了下面列出的内容之外,我没有做任何更改。
当我运行以下内容时,测试工作正常。请注意,在此版本中,服务在执行任何类型的$ http调用之前返回一个值。
./应用程序/ JS /服务/ services.js
'use strict';
angular.module('myApp.services', [])
.factory("exampleService", function ($http) {
return {value:"goodValue"};
$http.get("/exampleUrl")
.success(function () {
return {value:"goodValue"};
})
.error(function () {
return {value:"badValue"};
})
});
./测试/单元/ servicesSpec.js
'use strict';
describe('service', function() {
var $httpBackend;
beforeEach(module('myApp.services'));
beforeEach(inject(function ($injector) {
$httpBackend = $injector.get("$httpBackend");
$httpBackend.when("GET", "/exampleUrl")
.respond({value:"goodValue"});
}));
afterEach(function () {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
describe('exampleService', function () {
it('.value should be "goodValue"', inject(function (exampleService) {
expect(exampleService.value).toEqual("goodValue");
}));
});
});
info (watcher): Changed file "/home/username/mocktest/test/unit/servicesSpec.js".
Chrome 26.0: Executed 5 of 5 SUCCESS (0.136 secs / 0.035 secs)
当我删除行return {value:"goodValue"};
并实际让它运行$http.get()
时,整个事情就会出现以下错误:
info (watcher): Changed file "/home/username/mocktest/app/js/services.js".
Chrome 26.0 service exampleService .value should be "goodValue" FAILED
TypeError: Cannot read property 'value' of undefined
at null.<anonymous> (/home/username/mocktest/test/unit/servicesSpec.js:22:28)
at Object.invoke (/home/username/mocktest/app/lib/angular/angular.js:2864:28)
at workFn (/home/username/mocktest/test/lib/angular/angular-mocks.js:1758:20)
Error: Declaration Location
at window.jasmine.window.inject.angular.mock.inject (/home/username/mocktest/test/lib/angular/angular-mocks.js:1744:25)
at null.<anonymous> (/home/username/mocktest/test/unit/servicesSpec.js:21:40)
at null.<anonymous> (/home/username/mocktest/test/unit/servicesSpec.js:20:3)
at /home/username/mocktest/test/unit/servicesSpec.js:4:1
Error: Unflushed requests: 1
at Error (<anonymous>)
at Function.$httpBackend.verifyNoOutstandingRequest (/home/username/mocktest/test/lib/angular/angular-mocks.js:1225:13)
at null.<anonymous> (/home/username/mocktest/test/unit/servicesSpec.js:17:18)
Chrome 26.0: Executed 5 of 5 (1 FAILED) (0.14 secs / 0.043 secs)
我怀疑我需要在服务中做一些promise对象的返回,然后再解决它,但我不知道那会是什么。任何帮助表示赞赏。
答案 0 :(得分:12)
您怀疑的解决方案是正确的 - 承诺是解决错误/失败测试的关键。
使用原始$http
服务有条件地返回工厂对象不起作用,因为您实际上从工厂函数返回 nothing (由于{{1的异步承诺解析) }})。
我考虑过将$http
放在原来的return
电话前面。但这不是理想的行为,因为AngularJS $http.get()
方法应返回您定义的服务对象,而不仅仅是调用.factory
返回的承诺。
解决方案是在您的应用程序可以调用的$http
对象上公开一个方法。 exampleService
方法返回一个承诺(通过getData()
),您的应用/测试可以使用$http
或.success()
./应用程序/ JS /服务/ services.js
.error()
./测试/单元/ servicesSpec.js
'use strict';
angular.module('myApp.services', [])
.factory("exampleService", function ($http) {
return {
getData: function () {
return $http.get("/exampleUrl");
}
}
});
请注意,Destron关于'use strict';
describe('service', function() {
var $httpBackend;
beforeEach(module('myApp.services'));
beforeEach(inject(function ($injector) {
$httpBackend = $injector.get("$httpBackend");
$httpBackend.when("GET", "/exampleUrl")
.respond(200, {value:"goodValue"});
}));
afterEach(function () {
$httpBackend.flush()
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
describe('exampleService successful http request', function () {
it('.value should be "goodValue"', inject(function (exampleService) {
exampleService.getData().success(function(response) {
expect(response.value).toEqual("goodValue");
}).error( function(response) {
//should not error with $httpBackend interceptor 200 status
expect(false).toEqual(true);
});
}));
});
});
的评论对于让模拟后端拦截来自您服务的$httpBackend.flush()
请求也很重要。
希望有所帮助。