【发布时间】:2014-09-27 09:08:25
【问题描述】:
尝试测试返回$http GET 请求和then 处理程序的角度服务,但我无法测试该逻辑在then 函数内部是否有效。这是服务代码的基本截断版本:
angular.module('app').factory('User', function ($http) {
var User = {};
User.get = function(id) {
return $http.get('/api/users/' + id).then(function (response) {
var user = response.data;
user.customProperty = true;
return user;
});
};
return User;
});
这是测试:
beforeEach(module('app'));
beforeEach(inject(function(_User_, _$q_, _$httpBackend_, _$rootScope_) {
$q = _$q_;
User = _User_;
$httpBackend = _$httpBackend_;
$scope = _$rootScope_.$new();
}));
afterEach(function () {
$httpBackend.verifyNoOutstandingRequest();
$httpBackend.verifyNoOutstandingExpectation();
});
describe('User factory', function () {
it('gets a user and updates customProperty', function () {
$httpBackend.expectGET('/api/users/123').respond({ id: 123 });
User.get(123).then(function (user) {
expect(user.customProperty).toBe(true); // this never runs
});
$httpBackend.flush();
});
});
我觉得我已经尝试了几乎所有方法来测试then 调用中的逻辑,所以如果有人可以提供建议,我将不胜感激。
编辑:我的问题也是由于不标准的注入做法,所以下面的答案在此之外起作用。
【问题讨论】:
-
如果您在服务中执行此操作,那么您将没有应用范围。所以,我总是将承诺链的东西放在我的控制器中并在那里进行测试。这是一个类似问题的链接stackoverflow.com/a/24407839/2740086
-
谢谢。是的,当我在控制器中测试工厂的使用时,我能够传递一个虚假的承诺,但我想测试工厂承诺内部的逻辑是否合理。这只是不好的做法吗?
-
我所做的是:我在控制器中分离了promise的东西,所以我可以用promise.resolve()然后$scope.apply()来控制它。然后,我将成功或失败对象传递给“解析器”服务,该服务实际上会根据成功或失败执行我想要的操作。基本上,该服务有一个 getResourceFromServer() 方法和一个 resolveGetResourceFromServer(objectFromServer, successBool) 方法,我用来在服务中做任何事情。我不知道这是否是“最佳实践”,但我发现它使测试更容易一些。
标签: angularjs unit-testing jasmine karma-jasmine angular-promise