引用的SO是一个非常有用的问题,答案非常有用。但是,这之后我剩下的问题是:如何对模态实例控制器进行单元测试?在引用的SO中,测试了调用控制器,但模拟了模态实例控制器。可以说后者也应该进行测试,但是事实证明这非常棘手。原因如下:
我将在此处从引用的SO复制相同的示例:
.controller('ModalInstanceCtrl', function($scope, $modalInstance, items){ $scope.items = items; $scope.selected = { item: $scope.items[0] }; $scope.ok = function () { $modalInstance.close($scope.selected.item); }; $scope.cancel = function () { $modalInstance.dismiss('cancel'); }; });
因此,我首先想到的是,我将直接在测试中实例化该控制器,就像在测试中的其他任何控制器一样:
beforeEach(inject(function($rootScope) { scope = $rootScope.$new(); ctrl = $controller('ModalInstanceCtrl', {$scope: scope}); });
这不起作用,因为在这种情况下,angular没有提供注入$modalInstance的提供程序,因为它是由UI模态提供的。
接下来,我转向计划B:使用$ modal.open实例化控制器。这将按预期运行:
beforeEach(inject(function($rootScope, $modal) { scope = $rootScope.$new(); modalInstance = $modal.open({ template: '<html></html>', controller: 'ModalInstanceCtrl', scope: scope }); });
(请注意,模板不能为空字符串,否则会因密码错误而失败。)
现在的问题是,我对范围没有任何了解,这是对单元测试资源收集进行惯用的方式,等等。在我的真实代码中,控制器调用资源服务来填充选择列表。我对此进行的测试尝试设置了一个ExpectGet来满足控制器使用的服务,并且我想验证控制器是否将结果放入其范围内。但是模态正在为模态实例控制器创建一个 新的 作用域(使用我作为原型传入的作用域),我无法弄清楚如何获得该作用域的漏洞。modalInstance对象没有进入控制器的窗口。
关于“正确”的测试方法有什么建议吗?
(注意:为模态实例控制器创建派生范围的行为并非意外-这已得到记录,这是我的问题,无论如何,它的测试仍然有效。)
我通过直接实例化控制器来测试模式对话框中使用的控制器(与您最初在上面所做的相同)。
由于没有$modalInstance的模拟版本,我只需创建一个模拟对象并将其传递给控制器即可。
$modalInstance
var modalInstance = { close: function() {}, dismiss: function() {} }; var items = []; // whatever... beforeEach(inject(function($rootScope) { scope = $rootScope.$new(); ctrl = $controller('ModalInstanceCtrl', { $scope: scope, $modalInstance: modalInstance, items: items }); }));
现在,控制器的依赖关系已满足,您可以像其他任何控制器一样测试该控制器。
例如,我可以这样做spyOn(modalInstance,'close'),然后断言我的控制器正在适当的时间关闭对话框。
spyOn(modalInstance,'close')