2014-12-04 98 views
0

我想寫一個單元測試的AngularJS指令(這是包裝在一個模塊中需要通過requirejs),加載與requirejs模塊,但我有問題與全球對象在angular中加載時。嘲笑AngularJS單元測試的窗口對象

我目前的理解是,我需要實例化一個角度的應用程序,添加我的指令,然後讓角度編譯器在包含指令名稱的HTML上運行。從那時起,我可以像往常一樣進行測試。

然而,當嘗試要求angular在我的測試,我得到以下錯誤:

Uncaught Error: Evaluating c:\...\angular.js as module "angular" failed with error: ReferenceError: window is not defined 

有人建議,爲了得到一個窗口對象安裝jsdom,但是從上面的錯誤消息,則可能能夠弄清楚我在Windows環境中,而且這種組合看起來很痛苦。

此刻,我的測試很簡單:

// Imports, including requirejs config 

describe("Directive tests", function() { 
    var angular; 
    before(function(done) { 
     requirejs(['angular'], function(a) { 
      angular = a; 
     }); 
    }); 
}); 

我可以下去定義在requirejs一個window模塊的路線,並在測試注入一個模擬版本,但似乎像很多工作。

回答

0

根據定義,單元測試應該與其他所有單元隔離地進行測試。你不應該需要一個窗口,或任何東西的require

例如,這裏是一個指令單元測試,啓動一個「確認」彈出窗口。它使用摩卡,但你可以使用茉莉花或任何你想要的。


    describe('confirm', function(){ 
     var element, scope, msg = "Are you sure?", html = 'ABC', spy, stub; 
     beforeEach(function() { 
      var self = this; 
      stub = sinon.stub(); 
      self.$modal = { 
       open: function() { 
        return { 
         result: { 
          then: stub 
         } 
        }; 
       } 
      }; 
      spy = sinon.spy(self.$modal,"open"); 

      mod('GP.directives',{$modal:self.$modal}); 
      inject(function ($compile,$rootScope) { 
       element = angular.element(html); 
       scope = $rootScope; 
       scope.foo = sinon.spy(); 
       $compile(element)(scope); 
       scope.$digest(); 
       element.triggerHandler('click'); 
       scope.$digest(); 
      }); 
     }); 
     it('should call $modal.open when click the element', function(){ 
      spy.calledOnce.should.be.true; 
     }); 
     it('should set up with "then"', function(){ 
      stub.calledOnce.should.be.true; 
     }); 
     it('should have a single function argument to "then"', function(){ 
      stub.firstCall.args[0].should.be.type("function"); 
     }); 
     it('should not call the action when click the element', function(){ 
      scope.foo.called.should.be.false; 
     }); 
    }); 

注意,該指令與交互的唯一的事情是:

  • $modal - OK,我掐滅了這一點
  • 的HTML,這是我在使用$compile(angular.element(html))

通過這使我可以完全孤立地進行測試。實際上你需要一個window對象來進行單元測試應該是非常罕見的。

1

$window服務是爲此目的。只需在需要的地方注入它。

從文檔:

angular.module('windowExample', []) 
    .controller('ExampleController', ['$scope', '$window', function($scope, $window) { 
     $scope.greeting = 'Hello, World!'; 
     $scope.doGreeting = function(greeting) { 
     $window.alert(greeting); 
    }; 
}]); 
+1

但這個錯誤發生時嘗試需要的角度,我不能得到儘可能注射服務。 Angular是在requirejs config map中定義的,所以需要像上面那樣加載,不是嗎? – chooban 2014-12-04 15:44:40