$ http请求未运行服务测试

时间:2014-08-14 13:32:22

标签: angularjs testing jasmine

我对服务对象进行了以下测试,并且promise没有返回,也没有从服务内部调用http请求,但它在浏览器测试中有效。

'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;
    });
  };

...

我在测试中做错了什么?

我知道我的代码也很糟糕,但是如果我可以测试一下那么我就在那里。

1 个答案:

答案 0 :(得分:0)

如果您不想模仿$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

然后,我们调用whenPOST的{​​{1}}。基本上它做了类似的事情:

  

当有人对$httpBackend发帖时,请以200

回复

然后在测试中,我们调用/login来执行login。要处理此$http.post,因为它是异步的,我们可以模拟执行$http.post的真实调用,这将进行"处理"电话。

之后,我们可以验证$httpBackend.flush()是否已执行。

.then怎么样?在这个例子中我们并不真的需要它,但是如果你想断言是或者是的话,你可以将afterEach更改为whenPOST,如果测试失败,永远不会expectPOST。 afterEach基本上是检查POST的状态,看看是否有任何匹配的预期。

另一方面,您不需要手动创建承诺。 $httpBackend会为您返回一个承诺,因此您可以直接返回$http来电,并$http $http即可:

then

这将简化实现。

演示here