[英]Leaflet plugin not available in AngularJS controller during unit tests
我正在使用 Karma + Mocha 在 Angular 中測試控制器。 下面的代碼是控制器和測試規范的簡化示例。 L.Control.Locate
是一個LeafletJS 插件。
問題
在測試運行期間, L.Control.Locate
在控制器實例化時應該存在,但它不存在。 它拋出: TypeError: L.Control.Locate is not a constructor
。
該應用程序在瀏覽器中按預期工作。
PhantomJS 和 Chrome 中都會出現該錯誤。
在測試中,我使用調試器證實了之前MapCtrl2
是instantianted, L.Control.Locate
聲明並連接到window.L.Control
理所應當的,但控制器進行實例化之前它迷路。
L
的其他標准屬性正如預期的那樣存在。
當我在控制器聲明之前將L.Control.Locate.js
粘貼到文件中時,錯誤消失了。
我還嘗試將$window
注入控制器並查看$window.L.Control.Locate
,但它仍未定義。
感謝您提供任何線索。
代碼:
angular.module('app')
.controller('MapCtrl2', function ($scope) {
// Throws error here.
var locateControl = new L.Control.Locate();
// Do something with locateControl.
});
describe('MapCtrl2', function () {
var controller, scope;
beforeEach(module('app'));
beforeEach(inject(function ($controller, $rootScope) {
scope = $rootScope.$new();
controller = $controller('MapCtrl2', {
$scope: scope
});
}));
it('has L.Control.Locate', function() {
expect(window.L.Control.Locate).to.be.an.instanceOf(Object)
});
});
更新:
關於在全球范圍內使用L
的問題,我意識到L
可以通過$window.L
。 盡管這對許多 AngularJS 開發人員來說可能是顯而易見的,但我忽略了它。
要模擬您的庫對象,您需要類似的東西
beforeEach( function() { window.L = { Control: { Locate: function() { self = this; //populate based on the API you're mocking self.someMethod = angular.noop; self.someProp = 'foo'; } } } } }
然后您想監視這些方法以確保您的控制器按預期調用它們,或讀取屬性,以確保您的控制器按預期設置它們。
注意我繼承了將自身附加到窗口對象的代碼(哎呀!)。 我盡可能隱藏這種依賴。 我永遠不會讓控制器直接觸摸它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.