Angularjs $http请求未运行服务测试
我对服务对象进行了以下测试,承诺不会返回,http请求也不会从服务内部被调用,但它在浏览器测试中起作用Angularjs $http请求未运行服务测试,angularjs,testing,jasmine,Angularjs,Testing,Jasmine,我对服务对象进行了以下测试,承诺不会返回,http请求也不会从服务内部被调用,但它在浏览器测试中起作用 'use strict'; describe('Service: AuthService', function () { // load the controller's module beforeEach(module('adminPanelAngularApp')); var AuthService, AuthService, $rootScope; // Init
'use strict';
describe('Service: AuthService', function () {
// load the controller's module
beforeEach(module('adminPanelAngularApp'));
var AuthService, AuthService, $rootScope;
// Initialize the controller and a mock scope
beforeEach(inject(function (_AuthService_, _$rootScope_) {
AuthService = _AuthService_;
$rootScope = _$rootScope_;
}));
it('it auths', function () {
AuthService.login(SOMECREDENTIALS).then(function(){
console.log('this doesnt output in log');
});
expect(3).toBe(3);
});
});
这是我的服务
angular.module('adminPanelAngularApp').factory('AuthService', ['$http', '$cookieStore', '$rootScope', '$location', '$q', function ($http, $cookieStore, $rootScope, $location, $q) {
var authService = {};
....
authService.get_current_user = function(){
return $rootScope.current_user;
}
authService.login = function (credentials) {
var url = REDACTED;
return $http.post(server+url).then(function (res) {
if (!res.data){
return false;
}
if (res.data.error){
$rootScope.login_error = res.data.error;
}
var user = {
email: res.data.email,
session: res.data.session,
uid: res.data.uid
}
$cookieStore.put('loginData', user);
$rootScope.current_user = user;
return user;
});
};
...
我在考试中做错了什么
我知道我的代码也很糟糕,但如果我能测试这一点,我就成功了。如果你不想模仿$http,我建议你使用$httpBackend
使用$httpBackend,您可以使用$http模拟调用
想象一下这项服务:
app.factory('Auth', function($http) {
return {
login: function() {
return $http.post('/login');
}
};
});
我们的目标是测试您是否生成了$http.post,并且它是否成功返回,因此我们的想法如下:
describe('Service: Auth', function() {
var Auth, $httpBackend;
beforeEach(function() {
module('app');
inject(function(_Auth_, _$httpBackend_) {
Auth = _Auth_;
$httpBackend = _$httpBackend_;
$httpBackend.whenPOST('/login').respond(200);
});
});
afterEach(function() {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
it('should do a proper login', function() {
var foo;
Auth.login().then(function() {
foo = "success";
});
$httpBackend.flush();
expect(foo).toBe("success");
});
});
因此,对于初学者,我们注入了我们需要的Auth和$httpBackend
然后,我们称之为$httpBackend的whenPOST。基本上是这样的:
当有人发帖子/登录时,回复200
然后在测试中,我们调用login,它将执行$http.post。要处理这个$http.post,因为它是异步的,所以我们可以模拟真正的调用,使用$httpBackend.flush来处理调用
之后,我们可以验证.then是否已执行
那以后呢?在本例中,我们并不真正需要它,但当您想要断言调用是或是时,您可以将whenPOST更改为expectPOST,以使测试失败(如果从未发出该POST)。afterEach基本上是检查$httpBackend的状态,看看是否有任何期望不匹配
另一方面,您不需要手工创建承诺$http为您返回承诺,因此您可以直接返回$http调用,然后在$http上您可以:
这将稍微简化实现
演示我想从真正的请求开始。从我最初的问题中删除承诺用法,因为我试图在不知道angular对后端做了什么的情况下强行通过结果。我想要一个解决方案,我可以使用一个真正的请求,直到我对我的规范感到满意,并将它们保存为模拟。不,这是不正确的。这是一个单元测试,意思是测试与世界其他地方隔离的工厂。永远不要在单元测试中执行真正的请求。这是完全错误的。事实上,angular mock有一些代码可以防止这种情况发生,但也有一些变通方法。我想做得不对,这样我就可以从测试套件中提取真实世界的响应并将其放入测试中,而不必使用postman或curl之类的其他方法。干杯
return user;