【问题标题】:Mocking ngModel in unit tests在单元测试中模拟 ngModel
【发布时间】:2015-05-04 14:16:29
【问题描述】:

我正在尝试为使用链接函数且没有任何关联模板的指令编写单元测试。该指令需要ngModel,如下所示:

angular.module('some-module', []).directive('someDirective', function() {
  return {
    restrict: 'A',
    require: 'ngModel',
    link: function(scope, element, attr, controller) {
      //Do something
    }
  };
});

当尝试对此进行单元测试时,我只是想编译一个 DIV 来触发指令:

var $scope = $rootScope.$new();
var element = $compile('<div some-directive></div>')($scope);
$scope.$digest();

但这会触发无法找到ngModel 控制器的错误。查看ngModelngModelController 的文档后,我尝试使用$provide 服务模拟ngModel,如下所示:

beforeEach(module(function($provide) {
  var mockNgModel = {};
  $provide.value('ngModel', mockNgModel); //Doesn't work
  $provide.value('ngModelCtrl', mockNgModel); //Doesn't work
  $provide.value('ngModel.NgModelController', mockNgModel); //Doesn't work
  $provide.value('ngModel.ngModelController', mockNgModel); //Doesn't work
}));

我还看到了其他解决方案,它们讨论在范围内创建一个属性,该属性包含在使用您的指令的 HTML 中绑定的任何ngModel(例如solution1solution2),但这有没有解决我的错误。

【问题讨论】:

    标签: javascript angularjs unit-testing


    【解决方案1】:
    var $scope = $rootScope.$new();
    $scope.foo = 'bar';
    var element = $compile('<div some-directive ng-model="foo"></div>')($scope);
    $scope.$digest();
    

    【讨论】:

    • 我仍然遇到同样的错误。这对你有用吗?如果是这样,那么我可能需要在我的代码中找出另一个问题。
    • 是的,检查一下:jsfiddle.net/A8Vgk/1232 如果我遗漏了 ng-model,我会收到您描述的错误。
    • 看来你是对的。出于某种原因,它试图模拟导致错误的ngModel。当我删除这些行并在 HTML 标记中指定 ng-model 时,我不再收到错误消息。我想知道你是否不应该尝试在单元测试中模拟ngModel
    • 我不会模拟任何框架的东西,因为我们不会模拟核心 JS 函数和像数学库这样的库。我的理由是所有的 Angular 框架都经过单元测试,所以我们希望它们能像宣传的那样工作。模拟 ngModel 对开发人员也没有任何便利或好处。
    • 编写一个测试,证明你的指令正确地扩展为你期望的元素。为了证明模板正在使用模型,您可以使用 jQuery 选择器来查找该元素并检查其内容。 expect(testElement.html()).toContain('我的模型值');为了证明它的工作方式相反,做一些会导致你的指令改变模型的事情,然后只测试范围属性:expect(scope.myProperty).toEqual('bananas');在这两种情况下,我们实际上不需要直接对 ngModel 做任何事情,除非确保它正在我们的设置中使用。
    猜你喜欢
    • 2019-12-13
    • 2017-02-09
    • 2018-11-27
    • 1970-01-01
    • 2016-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多