我将 Jasmine 和 Karma 一起使用,以测试基于 Angular 构建的应用程序。
我必须测试加载用户数据的服务,并且使用 $ httpBackend 模拟响应。但是,当我运行测试时,出现两个错误:
模块:
'use strict'; app.service ('UserService', ['$resource', '$q', 'GITHUB_API_URL', function ($resource, $q, GITHUB_API_URL) { var userResource = $resource (GITHUB_API_URL + '/users/:user', {user: '@user'}) , userModel = {}; return { data: function () { return userModel; } , populate: function (user) { var deferred = $q.defer () , userRequest = userResource.get ({user: user}); $q .when (userRequest.$promise) .then (function (data) { userModel = data; deferred.resolve (data); }); return deferred.promise; } }; }]);
测试:
'use strict'; describe ('Service: UserService', function () { beforeEach (module ('myApp')); var $appInjector = angular.injector (['myApp']) , UserService = $appInjector.get ('UserService') , GITHUB_API_URL = $appInjector.get ('GITHUB_API_URL') , GITHUB_USER = $appInjector.get ('GITHUB_USER') , $httpBackend; beforeEach (inject (function ($injector) { $httpBackend = $injector.get ('$httpBackend'); $httpBackend .when ('GET', GITHUB_API_URL + '/users/' + GITHUB_USER) .respond ({ login: GITHUB_USER , id: 618009 }); })); afterEach (function () { $httpBackend.verifyNoOutstandingExpectation (); $httpBackend.verifyNoOutstandingRequest (); }); describe ('when populate method is called', function () { it ('should returns user data', function () { $httpBackend.expectGET (GITHUB_API_URL + '/users/' + GITHUB_USER); UserService.populate (GITHUB_USER); $httpBackend.flush (); expect(UserService.data ()).toEqual ({ login: GITHUB_USER , id: 618009 }); }); }); });
假设GITHUB_API_URL等于 ‘ https://api.github.com/ ‘,_而GITHUB_USER等于 ‘wilk’_ 。
我正在使用 Karma-Jasmine 0.1.5 和 AngularJS 1.2.6 (使用Angular Mocks和方案1.2.6)运行此测试。
此代码有什么问题?
让我们分别讨论每个错误:
错误:没有等待刷新的请求!
发生这种情况是因为没有通过请求$httpBackend,所以没有要刷新的东西。那是因为您在实例化UserService之前$httpBackend,所以Angular不知道它应该使用它而不是real $http。如果您检出控制台,您会看到正在发送真实请求。
$httpBackend
UserService
$http
错误:请求不满意:GET https://api.github.com/users/wilk
与上述相同的原因。由于$httpBackend服务未使用该服务,因此您创建的期望将永远无法实现。
考虑以上所有因素后,重构的规格如下:
describe ('Service: UserService', function () { var UserService, GITHUB_API_URL, GITHUB_USER, $httpBackend; beforeEach(function() { module('plunker'); inject(function( _$httpBackend_, _UserService_, _GITHUB_API_URL_, _GITHUB_USER_) { $httpBackend = _$httpBackend_; UserService = _UserService_; GITHUB_API_URL = _GITHUB_API_URL_; GITHUB_USER = _GITHUB_USER_; }); }); afterEach (function () { $httpBackend.verifyNoOutstandingExpectation (); $httpBackend.verifyNoOutstandingRequest (); }); describe ('when populate method is called', function () { it ('should returns user data', function () { $httpBackend .whenGET(GITHUB_API_URL + '/users/' + GITHUB_USER) .respond ({ login: GITHUB_USER, id: 618009 }); UserService.populate(GITHUB_USER); $httpBackend.flush(); expect(UserService.data().login).toBe(GITHUB_USER); expect(UserService.data().id).toBe(618009); }); }); });
柱塞
注意:我已经更改了一些注入方式,但是只要您先创建$httpBackend其他内容,您的操作就可以了。