1

在我的 Angular JS 应用程序中,我有一个 mainController,它以 userFactory 作为参数。userFactory 由一个名为 userService 的对象组成,该对象又具有一个 userDetails 对象和一些方法,包括 resetUserDetails。(见下文)

在 mainController 我有一个调用该userFactory.userService.resetUserDetails方法的 logOut 函数。我想用 jasmine 测试这个 logOut 函数,但是我遇到了一些错误。我对茉莉花很陌生,所以如果我遗漏了一些明显的东西,我深表歉意。

所以首先在我的 Jasmine 套件中,我创建了一个 MainControllerSpec 来测试我的 mainController。

在这个规范中,我注入了一个名为 userFactory 的工厂。我正在尝试resetUserDetails按如下方式监视我的方法,但是出现错误:

spyOn(userFactory, 'userService.resetUserDetails');

错误:userService.resetUserDetails()不存在。

我通过在我的 userFactory(在 userService 对象之外)创建一个名为 test 的函数来尝试这个过程,它运行良好,所以至少我知道规范中的工厂注入设置得很好。
非常感谢任何帮助。谢谢

MainControllerSpec.js

describe("MainController", function () { 
    beforeEach(angular.mock.module('mapModule', 'ngRoute','ngTouch', 'ngAnimate'));
    var scope, userFactory; 

    beforeEach(inject(function($rootScope, $controller, _userFactory_){
        scope = $rootScope.$new();
        userFactory = _userFactory_;
        $controller('mainController', {
            $scope: scope
        }); 
    }));


   describe('The logOut function', function() {
        it('should call the resetUserDetails function of the userFactory.userService object and reset the userDetails object', function() {
            //spyOn takes in a factory and a method of that factory 
            spyOn(userFactory, 'userService.resetUserDetails');
            //spyOn(userFactory, 'test'); tried this and it works.
            scope.logOut();
            expect(userFactory.userService.resetUserDetails).toHaveBeenCalled();  
        });
    });

});

mainController 中的 logOut 函数

   $scope.logOut = function(){
         userFactory.userService.resetUserDetails(); 
         //userFactory.test(); //tried this with spyOn in jasmine
    }

用户工厂

mapApp.factory('userFactory', function(){

    var userService = {
        /*
         * Initialize a userDetails object. 
         */
        userDetails : {   
            "userID" : null,
            "facebookUserID" : "",
            "facebookName" : "",
            "facebookProfilePic" : "",
            "userPrivilegeID" : 1,
            "userToken" : "",
            "isLoggedIn" : false
        },
        resetUserDetails : function(){
            /*
             * This method resets the userDetails object.
             */
            this.userDetails = {
                "userID" : null,
                "facebookUserID" : "",
                "facebookName" : "",
                "facebookProfilePic" : "",
                "userPrivilegeID" : 1,
                "userToken" : "",
               "isLoggedIn" : false
            };
        }
    }; 
    var test = function(){
        /*
        * for testing spyOn in Jasmine
        */
    };
    //return public API so that we can access it in all controllers
    return{
      userService: userService,
      test: test
    };
});
4

1 回答 1

1

你需要模拟你的userFactory之前直接注入它。单元测试的目标是将文件作为黑盒进行测试,而不是直接测试相关方法的逻辑。

对于他们,您将为他们编写您的规范文件userFactory

在这种情况下,您可以执行以下操作:

describe("MainController", function() {

  beforeEach(angular.mock.module('mapModule', 'ngRoute', 'ngTouch', 'ngAnimate'));
  var scope, userFactory;

  // here mock the methods of your factory
  beforeEach(module(function($provide) {
    $provide.value('userFactory', {
      myFirstObject: {
        myFirstMethod: function() {}
      }
    });
  }));

  beforeEach(inject(function($rootScope, $controller, _userFactory_) {
    scope = $rootScope.$new();
    userFactory = _userFactory_;
    $controller('mainController', {
      $scope: scope
    });
  }));


  describe('The logOut function', function() {
    it('should call the resetUserDetails function of the userFactory.userService object and reset the userDetails object', function() {
      //here spy on the method and return what you would like to return in this test
      // or if you don't need to manage the return, as it seems you don't, just use callThrough
      spyOn(userFactory.myFirstObject, 'myFirstMethod').and.callThrough();
      scope.logOut();
      expect(userFactory.myFirstObject.myFirstMethod).toHaveBeenCalled();
    });
  });

});

于 2017-10-08T18:52:57.083 回答