gpt4 book ai didi

unit-testing - 在服务单元测试中使用 ngMock 模拟 $http 调用

转载 作者:行者123 更新时间:2023-12-04 04:12:35 28 4
gpt4 key购买 nike

我已经看了好几个小时了。我试过一个又一个例子。我似乎无法让它发挥作用。请帮忙=)

我在 angular-seed repo (git://github.com/angular/angular-seed.git) 的一个干净克隆上做所有这些。除了下面列出的那些,我没有做任何改变。

问题:

当我运行以下命令时,测试有效。请注意,在此版本中,该服务会在执行任何类型的 $http 调用之前返回一个值。

./app/js/services/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"};
})
});

./test/unit/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 对象,然后再解决它,但我不知道那会是什么。任何帮助表示赞赏。

最佳答案

您怀疑的解决方案走在正确的轨道上 - promise 是修复错误/失败测试的关键。

使用您原来的 $http有条件地返回工厂对象的服务不起作用,因为您实际上没有从工厂函数返回任何内容(由于 $http 的异步 promise 解析)。

我考虑过放 return在你原来的前面$http.get()称呼。但这不是我们想要的行为,因为 AngularJS .factory方法应该返回您定义的服务对象,而不仅仅是调用 $http 所返回的 promise 。 .

解决方案是在您的 exampleService 上公开一个方法可以由您的应用程序调用的对象。那个getData()方法返回一个 promise (通过 $http ),您的应用程序/测试可以使用 .success() 异步处理该 promise 或 .error()
./app/js/services/services.js

'use strict';
angular.module('myApp.services', [])
.factory("exampleService", function ($http) {
return {
getData: function () {
return $http.get("/exampleUrl");
}
}
});

./test/unit/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(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);
});

}));
});


});

请注意 Destron 关于 $httpBackend.flush() 的评论让模拟后端拦截 $http.get() 也很重要来自您的服务的请求。

希望有帮助。

关于unit-testing - 在服务单元测试中使用 ngMock 模拟 $http 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15927919/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com