2014-05-12 65 views
1

我正在與AngularJS一起構建一個cordova/phonegap應用程序。在我的應用程序中,我使用了來自cordova的一些本地插件,如地理位置插件。Jasmine:在不存在的窗口對象上創建間諜

在我的測試中,這個插件不可用(因爲phonegap不存在),$window.plugins在我的測試中返回undefined。當然,$window.plugins.anotherPlugin也失敗。

因此,我必須爲我的測試嘲笑這部分。目前,我做這樣

beforeEach(function() { 
    $window.plugins = { 
     anotherPlugin: { 
     foo: function() {} 
     } 
    }; 
    }); 

但是,如果在未來,另一個庫使用$window.plugins命名空間,我將其覆蓋在我的測試?這將打破其他測試。用上面的方法,我將不得不在我的測試後做一些清理工作,以確保$window.plugins的舊值被恢復。我認爲,這種方式不是很乾淨,我想知道是否有更好的方法來用茉莉花做到這一點。

所以我的問題是:我怎樣才能在$window.plugins.anotherPlugin間諜通過創建虛擬茉莉功能,而不會影響其他測試中,當$window.plugins不存在?

回答

1

您應該加載您想要測試的零件的模塊並生成一個提供間諜的模擬模塊。

beforeEach(function() { 
    module('ModuleUnderTest', function($provide) { 
     var windowMock = { 
      plugins: { 
       anotherPlugin: jasmine.createSpyObj('anotherPlugin', ['foo', 'bar']) 
      } 
     }; 

     // substitute all dependencies with mocks 
     $provide.value('$window', windowMock); 
    }); 
}); 

當心,我沒有測試代碼,但你應該得到的要點。

+0

看起來不錯。但是這會導致另一個問題:我有一個使用'$ window.moment.lang(lang);'的庫(angular moment.js)。當使用上面的方法時,它會拋出'TypeError:無法讀取未定義的屬性'lang'。任何想法如何解決這個問題? – 23tux

+0

你不能只是嘲笑這個功能嗎?如果你真的需要它,你可以在模塊初始化之前使用注入函數,抓住時刻對象並把它放在你的模擬對象上。例如var moment;注入(function($ window){moment = $ window.moment;}); module(...,function($ provide){windowMock.moment = moment; ...}); – Slashme