如何使用AngularJS持有变量进行单元测试?

时间:2014-06-30 14:41:55

标签: angularjs unit-testing karma-runner

我的控制器功能有:

$scope.openForgotPasswordModal = function() {
  var forgotPasswordModal;
  forgotPasswordModal = $modal.open({
    templateUrl: '/templates/passwordReset.html',
    scope: $scope,
    size: 'lg'
  });
  $scope.closeModal = function() {
    return forgotPasswordModal.close();
  };
};

测试模态的开放很容易:

it('should open a modal', function() {
  $scope.init();
  $scope.openForgotPasswordModal();
  expect($modal.open).toHaveBeenCalledWith({
    templateUrl: '/templates/passwordReset.html',
    scope: $scope,
    size: 'lg'
  });
  $scope.closeModal = function() {
    forgotPasswordModal.close();
  };
});

如何测试closeModal功能?

2 个答案:

答案 0 :(得分:2)

我在调用$ modal.open()时使用spyOn函数返回一个假对象:

var fakeModal, myController;
beforeEach(inject(function ($controller, $modal) {
    fakeModal = {
        result: {
            then: function (confirmCallback, cancelCallback) {
                //Store the callbacks for later use to mimic the click of the button.
                this.confirmCallBack = confirmCallback;
                this.cancelCallback = cancelCallback;
            }
        },
        close: function (result) {
            this.result.confirmCallBack(result);
        }
    };

    spyOn($modal, 'open').and.returnValue(fakeModal);

    myController = $controller('MyController', {
        $modal: $modal,
    });
 }));

然后,它可以监视fakeModal.close()并知道它是否被调用:

spyOn(fakeModal, 'close').and.callThrough();
$scope.closeModal();
expect(fakeModal.close).toHaveBeenCalled();

答案 1 :(得分:1)

考虑到这是一个单元测试而$ modal是一个外部依赖,测试它的正确方法是模拟$ modal:

var $modalMock = jasmine.createSpyObj('$modal', ['open']),
    forgotPasswordModalMock = jasmine.createSpyObj('$forgotPasswordModal', ['close']);
$modalMock.and.callFake(function(){
    return forgotPasswordModalMock;
});

beforeEach(angular.mock.module(function($provide){
    $provide.value('$modal', $modalMock);
}));

it('should open a modal', function() {
    $scope.init();
    $scope.openForgotPasswordModal();
    expect($modalMock.open).toHaveBeenCalledWith({
        templateUrl: '/templates/passwordReset.html',
        scope: $scope,
        size: 'lg'
    });
});
it('should close a modal', function(){
    $scope.closeModal();
    expect(forgotPasswordModalMock.close).toHaveBeenCalled();
})

如果$ modal被破坏,那么这个测试仍然应该通过,因为$ modal的内部工作超出了这个特定单元测试的范围。