测试注入服务的方法调用

时间:2016-02-02 12:03:55

标签: angularjs unit-testing dependency-injection factory karma-jasmine

试图弄清楚如何检查注入的Service上的方法。

服务(基于工厂):loginService.js

angular.module('loginService', [])
    .factory('loginService', function (URLbase, $http, loginModel, $route, $location, logoutService, overviewService) {
        return {
            logMeIn: function (login) {

                $http({
                    method: 'POST',
                    url: URLbase + 'authentication/login',
                    data: {'Login': login.username, 'Password': login.password}
                }).then(function (result) {

                        loginModel.set('passwordRequested', false);
                        loginModel.set('loginFailed', false);
                        loginModel.set('loginExpired', false);
                        loginModel.set('loginBlocked', false);
                        loginModel.set('loggedIn', false);
                        loginModel.set('sessionExpired', false);
                        loginModel.set('loggedIn', false);
                        loginModel.set('concurrentLogin', false);
                        loginModel.set('somethingWrong', false);

                        // Check login result by status code
                        var status = result.data.Response.Status.StatusCode,
                            data = result.data.Response.Payload;

                    switch (status) {
                        case 0:
                            loginModel.set('tokenToken', data.Token);
                            loginModel.set('tokenUserId', data.userId);
                            loginModel.set('userName', data.User.FirstName + ' ' + data.User.SurName);
                            loginModel.set('userFirstName', data.User.FirstName);
                            loginModel.set('userLastName', data.User.SurName);
                            loginModel.set('userEmailAddress', data.User.Email);
                            loginModel.set('userPhone', data.User.Phone);
                            loginModel.set('userPreferredLanguage', data.User.PreferredLanguage);
                            loginModel.set('loggedIn', true);
        ......

单元测试

beforeEach(inject(function ($controller, _$rootScope_, _$httpBackend_, $injector, _loginService_, _loginModel_) {
    loginService = _loginService_;
    httpBackend = _$httpBackend_;
    $rootScope = _$rootScope_;
    loginModel = _loginModel_;

    loginPost = {'Login': login.username, 'Password': login.password};
    httpBackend.whenPOST(URLbase + 'authentication/login', loginPost).respond(200, jsonObj);
}));

it('should get login data from the backend', function () {

    spyOn(loginService, 'logMeIn').andCallThrough();
    loginService.logMeIn(login);
    expect(loginService.logMeIn).toHaveBeenCalledWith(login);
    httpBackend.flush();

    //spyOn(loginModel, 'set').andCallThrough();
    //loginService >> logMeIn >> loginModel.set('userLastName', 'Vijver');
    //metod >> toHaveBeenCalledWith('userLastName', 'Vijver');
});

因此,在最后3条注释行中,我想测试是否使用正确的参数调用loginModel.set('userFirstName', data.User.FirstName);

我该如何管理?

1 个答案:

答案 0 :(得分:1)

您可以在调用内部测试结果:

logService.logMeIn(login).then(function(result) {
  expect(loginModel.set).toHaveBeenCalledWith('userFirstName',data.User.FirstName);
});

修改

你的功能应该这样做:

return {
        logMeIn: function (login) {

            return $http({..
        }
}

编辑

关于你的转换语句,我这样做,因为我希望尽可能减少成功和失败的部分:

$http({
  method: 'POST',
  url: URLbase + 'authentication/login',
  data: {'Login': login.username, 'Password': login.password}
}).then(function (result) {

  // This underscore is lodash syntax - which I'd recommend
  var loginStuff = ['passwordRequested','loginFailed','loginExpired',etc];
  _.forEach(loginDetails, function(detail) {
    loginModel.set(detail, false);
  });
  // Here I have immediately removed lines of redundant code.
  // I'd also suggest you go one further and place this into it's own    
  // function - which can be private to the service if you choose
});

这个相同的原理可以应用于开关。如果没有看到所有的开关情况,我就无法正确地重构它。