2014-10-27 166 views
6

我有一個角度的應用程序與一個控制器,在函數調用期間顯示Angular-Strap模態窗口。它在Chrome中正常運行,但我無法獲得有效的單元測試工作。

應用模塊和FooController的:

var app = angular.module("app", ["mgcrea.ngStrap"]); 

app.controller("FooController", function($scope, $modal) { 
    var fooModal = $modal({ 
     title: 'Foo', 
     content:'Bar', 
     show: false, 
     html: true, 
     backdrop: 'static', 
     placement: 'center'}); 

    angular.extend($scope, { 
     makeItFoo: function() { 
      fooModal.show(); 
     } 
    }); 
}); 

控制器規格:

describe('FooController', function() { 
    var scope, controller, modal; 

    beforeEach(module('app', function ($provide) { 
     // Stub out $modal service 
     $provide.value('$modal', function() { 
      return { 
       hide: function() { }, 
       show: function() { } 
      }; 
     }); 
    })); 

    beforeEach(inject(function ($rootScope, $controller, $injector) { 
     //set up a new scope and the controller for the test 
     scope = $rootScope.$new(); 
     controller = $controller('FooController', {$scope: scope}); 
     modal = $injector.get('$modal'); 
    })); 

    it('should show the modal', function() { 
     var modalSpy = spyOn(modal(), 'show'); 

     scope.makeItFoo(); 

     expect(modalSpy).toHaveBeenCalled(); 
    }); 
}); 

Here's a fiddle as well.

我希望我的呼籲makeItFoo()顯示模式,但茉莉失敗測試錯誤Expected spy show to have been called。我也嘗試將模式的show屬性設置爲true,而不是分別調用show(),並且我嘗試了對$ modal服務進行存根的其他變體,並將其直接注入到控制器中,但它最終出現相同的錯誤。

我使用的是AngularJS 1.2.14,Angular-Strap 2.0.0和Jasmine 1.3.1。

回答

7

而不是做這些。使用show和hide方法爲$modal創建一個模擬對象,並設置您對它們的期望。

describe('FooController', function() { 
    var scope, controller, modal; 

    beforeEach(module('app')); 

    beforeEach(inject(function ($rootScope, $controller) { 
     //set up a new scope and the controller for the test 
     scope = $rootScope.$new(); 
     //Create spy object 
     modal = jasmine.createSpyObj('modal', ['show', 'hide']); 
     //provide modal as dependency to the controller. 
     controller = $controller('FooController', {$scope: scope, $modal:modal}); 

    })); 

    it('should show the modal', function() { 

     scope.makeItFoo(); 

     expect(modal.show).toHaveBeenCalled(); 
    }); 
}); 
+1

我是我的答案,當你張貼它,你釘了它;) – maurycy 2014-10-27 18:54:30

+0

@maurycy哈哈它有時也發生在我身上.. :) – PSL 2014-10-27 18:55:00

+0

@PSL,謝謝!我試圖理解嘲笑$ modal的正確方法,這看起來就是這樣。但是,如您所描述的那樣更新了我的小提琴,測試仍然失敗。具體來說,錯誤現在讀取'參數'FooController'不是一個函數,得到undefined';更新小提琴[這裏](http://jsfiddle.net/dimmreaper/jwom7ns2/3/)。 – 2014-10-27 20:16:21

1

模式顯示是異步的。我更新了你的小提琴http://jsfiddle.net/jwom7ns2/1/。當模態顯示發生發生

it('should show the modal', function (done) { 
    var modalSpy = spyOn(modal(), 'show'); 

    scope.makeItFoo(); 

    setTimeout(function() { 
     expect(modalSpy).toHaveBeenCalled(); 
     done(); 
    }); 

}); 

超時包裝等待摘要:

更改以下部分。

+0

在你修改你的答案之前,我正要評論爲什麼'scope。$ apply' ?.但我認爲這可能是一個矯枉過正的恕我直言,因爲OP已經創建了一個模擬對象,然後設立間諜。相反,所有可以通過使用茉莉花創建一個模擬對象一次完成。你也不需要執行'$ injector.get('$ modal')',而是'$ modal'可以直接注入。 – PSL 2014-10-27 18:56:41

+1

謝謝,這絕對是一個可行的解決方案。我會首先給@ PSL嘲笑$ modal的方法,因爲我不想明確地處理時間。如果我在那裏遇到問題,我會記住你的解決方案。謝謝! – 2014-10-27 20:19:42