簡體   English   中英

在單元測試期間,AngularJS 控制器中沒有 Leaflet 插件

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM