【问题标题】:Javascript.confirm() and Angularjs Karma e2e testJavascript.confirm() 和 Angularjs Karma e2e 测试
【发布时间】:2013-05-07 17:20:51
【问题描述】:

我有一个 Angularjs 应用程序,它在执行某些操作之前使用简单的 javascript 确认。

控制器:

function TokenController($scope) {
  $scope.token = 'sampleToken';

  $scope.newToken = function() {
    if (confirm("Are you sure you want to change the token?") == true) {
      $scope.token = 'modifiedToken';
    }
  };
}

查看:

<div id="tokenDiv">
  Token:{{token}} <button ng-click="newToken()">New Token</button>
</div>

现在我想进行端到端测试以检查令牌在视图中是否被正确替换。如何拦截javascript.confirm() 调用,使其不会停止测试的执行?

测试:

it('should be able to generate new token', function () {
   var oldValues = element('#tokenDiv').text();
   element('button[ng-click="newToken()"]').click(); // Here the javascript confirm box pops up.
   expect(element('#tokenDiv').text()).not.toBe(oldValues);
});

到目前为止,我已尝试重新定义 window.confirm 函数,但实际调用抱怨它未定义。

我还想在 window.confirm 上设置 Jasmine 间谍,但在以下语法 spyOn(window, 'confirm'); 中它给了我一个错误,说你不能在 null 上进行间谍活动。

我将如何进行这样的测试?

【问题讨论】:

    标签: angularjs jasmine karma-runner angularjs-e2e


    【解决方案1】:

    另一种选择是直接创建间谍并自动返回true

    //Jasmine 2.0
    spyOn(window, 'confirm').and.callFake(function () {
         return true;
    });
    
    //Jasmine 1.3
    spyOn(window, 'confirm').andCallFake(function () {
         return true;
    });
    

    【讨论】:

    • 如果您不想更新代码以环绕 window.confirm 调用,则此答案非常有用。
    【解决方案2】:

    端到端测试

    请咨询本项目: https://github.com/katranci/Angular-E2E-Window-Dialog-Commands

    单元测试

    如果您为对话框创建服务,那么您可以在单元测试中模拟该服务,以使您的代码可测试:

    控制器

    function TokenController($scope, modalDialog) {
      $scope.token = 'sampleToken';
    
      $scope.newToken = function() {
        if (modalDialog.confirm("Are you sure you want to change the token?") == true) {
          $scope.token = 'modifiedToken';
        }
      };
    }
    

    modalDialog 服务

    yourApp.factory('modalDialog', ['$window', function($window) {
        return {
            confirm: function(message) {
                return $window.confirm(message);
            }
        }
    }]);
    

    modalDialogMock

    function modalDialogMock() {
        this.confirmResult;
    
        this.confirm = function() {
            return this.confirmResult;
        }
    
        this.confirmTrue = function() {
            this.confirmResult = true;
        }
    
        this.confirmFalse = function() {
            this.confirmResult = false;
        }
    }
    

    测试

    var scope;
    var modalDialog;
    
    beforeEach(module('yourApp'));
    
    beforeEach(inject(function($rootScope, $controller) {
        scope = $rootScope.$new();
        modalDialog = new modalDialogMock();
        var ctrl = $controller('TokenController', {$scope: scope, modalDialog: modalDialog});
    }));
    
    it('should be able to generate new token', function () {
       modalDialog.confirmTrue();
    
       scope.newToken();
       expect(scope.token).toBe('modifiedToken');
    });
    

    【讨论】:

      【解决方案3】:

      在单元测试中,您可以像这样模拟 $window 对象:

      你的测试:

      beforeEach(function() {
          module('myAppName');
      
          inject(function($rootScope, $injector) {
              $controller = $injector.get('$controller');
              $scope = $rootScope.$new();
              var windowMock = { confirm: function(msg) { return true } }
              $controller('UsersCtrl', { $scope: $scope, $window: windowMock });
          });
      });
      

      你的控制器:

      myAppName.controller('UsersCtrl', function($scope, $window) {
          $scope.delete = function() {
              var answer = $window.confirm('Delete?');
              if (answer) {
                   // doing something
              }
          }
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-12-26
        • 2018-08-20
        • 2014-05-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多