Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
对于这个使用$http服务的Angularjs登录控制器,我应该测试什么?_Angularjs_Unit Testing_Jasmine_Tdd_Karma Jasmine - Fatal编程技术网

对于这个使用$http服务的Angularjs登录控制器,我应该测试什么?

对于这个使用$http服务的Angularjs登录控制器,我应该测试什么?,angularjs,unit-testing,jasmine,tdd,karma-jasmine,Angularjs,Unit Testing,Jasmine,Tdd,Karma Jasmine,我正在做一个简单的应用程序(yo angular generator),它使用$http.get()通过身份验证工厂进行登录。如果成功,则“sessionId”值在local中设置为$localStorage。一切正常,但我在单元测试方面遇到了严重的问题。我无法在脑海中定义我应该测试什么! 这就是我的处境 控制器/logincontrollers.js angular.module('myApp') .controller('LoginCtrl',['$rootScope', '$scope',

我正在做一个简单的应用程序(yo angular generator),它使用$http.get()通过身份验证工厂进行登录。如果成功,则“sessionId”值在local中设置为$localStorage。一切正常,但我在单元测试方面遇到了严重的问题。我无法在脑海中定义我应该测试什么! 这就是我的处境

控制器/logincontrollers.js

angular.module('myApp')
.controller('LoginCtrl',['$rootScope', '$scope', '$location', '$localStorage', 'Auth', function ($rootScope, $scope, $location, $localStorage, Auth) {

  Auth.Logout();
  $rootScope.loginSucceeded = false;
  $scope.currentUser = {};

  $scope.login = function () {
    var formData = {
      username: $scope.username,
      password: $scope.password
    };

    Auth.Login(formData).then(function (response) {
      if (response.data.loginSucceeded === true && response.data.sessionId !== null) {
        $scope.currentUser = {username: $scope.username, sessionId: response.data.sessionId};
        $localStorage.currentUser = $scope.currentUser;
        $rootScope.loginSucceeded = true;
        window.location = '/';
      } else {
        $scope.error = 'Invalid credentials';
      }
    }, function (response) {
      $scope.error = 'Connection error';
      console.log(response);
    });
  };

}]);
服务/auth.js

angular.module('myApp')
.constant('baseURL', 'http://localhost:8080')
.factory('Auth',['$http', '$localStorage', 'baseURL', function ($http, $localStorage, baseURL) {

  return {
    Login: function (data) {
      return $http.get(baseURL + '/login', {
        params: data
      });
    },
    Logout: function () {
      delete $localStorage.currentUser;
    }
  };

}]);
服务器仅接受带有查询参数的登录请求

http://localhost:8080/login?username=Test&password=Test
现在是关键点。 这就是我在测试中所做的,没有错误

test/spec/logincontroller.js

describe('Controller: LoginCtrl', function () {

  // load the controller's module
  beforeEach(module('myApp'));

  var scope, $httpBackend, LoginCtrl;

  // Initialize the controller and a mock scope
  beforeEach(inject(function ($rootScope, _$httpBackend_, $controller, Auth) {
    $httpBackend = _$httpBackend_;
    scope = $rootScope.$new();
    LoginCtrl = $controller('LoginCtrl', {
      $scope: scope, Auth: Auth
      // place here mocked dependencies
    });
  }));
  afterEach(function() {
    $httpBackend.verifyNoOutstandingExpectation();
    $httpBackend.verifyNoOutstandingRequest();
  });


  it('should fetch sessionId', function() {
    $httpBackend.when('GET', 'http://localhost:8080/login', {params: {username: "Test", password: "Test"}})
    .respond({"sessionId":"c4b0b46a04b54247ac27f3bd4db289a0","loginSucceeded":true});
    scope.login();
    $httpBackend.flush();
  });

});
我尝试做的每一件事都会给我一个错误。 你能帮我了解一下,如果这个测试是好的,我应该测试什么?可能是表单,或者$localStorage或者什么? 你有没有认真的单元测试手册/资源/最佳实践给我建议

谢谢你的建议

---更新---

我得到了这个错误:

PhantomJS 2.1.1 (Mac OS X 0.0.0) Controller: LoginCtrl should fetch sessionId FAILED
        Expected undefined to equal 'c4b0b46a04b54247ac27f3bd4db289a0'.
        test/spec/controllers/logincontroller.js:44:36
        loaded@http://localhost:8081/context.js:151:17
PhantomJS 2.1.1 (Mac OS X 0.0.0): Executed 5 of 5 (1 FAILED) (0.008 secs / 0.063 secs)

关于测试,我的一般经验法则是

  • 只测试您正在测试的内容。如果您正在测试控制器,请仅测试此项
  • 为此,请模拟所有其他内容,在您的情况下,这将是auth服务
单独测试auth服务,并遵循类似的模式,模拟$http服务等等

所以我想说,你离这里不远,只要把它分成两个不同的测试套件(文件)


Mocking-wise我倾向于使用
$provide
创建一个空对象,然后
spy
监视我需要的函数并模拟数据的返回。这样,您就可以确切地知道调用了什么以及应该返回什么数据

这方面的一个例子是:

module(function($provide) {
  $provide.service('Auth', function() {
    this.logIn = jasmine.createSpy('logIn').andCallFake(function(params) {
      //a fake implementation
    });
    this.logOut = jasmine.createSpy('logOut').andCallFake(function(params) {
      //a fake implementation
    });
  });
});
这样做的美妙之处在于,您可以断言/期望函数被这样调用

expect(Auth.LogIn).toHaveBeenCalled();
您还可以执行更高级的操作,例如检查是否使用特定参数调用了它。关于这一点,有很多容易访问的内容,你可以在谷歌上搜索,现在你知道该找什么了


注意上面的代码是手工编写的,因此可能会有轻微的错误。这显示了Jasmine v2的功能。

您的测试对我很好。我可以建议测试工厂而不是控制器谢谢你的建议。你能不能说得更清楚一点“模仿其他一切”。在我的例子中,我应该如何模拟Auth服务呢?你能给我举个例子吗。谢谢
expect(Auth.LogIn).toHaveBeenCalled();