【发布时间】:2023-03-29 17:47:01
【问题描述】:
我有一个控制器可以从不同的地方更改一些 DOM。
控制器是:
angular.module('myModule').controller('myController', myController);
function myController() {
this.addSomeClass = function() {
$('#idOfSomeElement').addClass('someClass');
};
}
而且它是这样使用的。里面不同的组件和html。
<div id="idOfSomeElement"></div>
.
.
.
<some-angular-component-here>
<div ng-controller="myController as ctrl">
<div ng-click="ctrl.addSomeClass()"></div>
</div>
</some-angular-component-here>
.
.
.
<using-in-onother-place>
<div ng-controller="myController as ctrl">
<div ng-click="ctrl.addSomeClass()"></div>
</div>
</using-in-onother-place>
我尝试像这样测试它,但我有未定义的 ctrl。
describe('Controller test', function () {
'use strict';
var ctrl,
element;
beforeEach(inject(function ($rootScope, $compile) {
var scope = $rootScope.$new();
angular.element('<div id="idOfSomeElement"></div>' +
'<div ng-controller="myController as ctrl">' +
'<div id="button" ng-click="ctrl.addSomeClass()"></div>' +
'</div>');
element = $compile(element)(scope);
scope.$apply();
// how to get controller here with linked to html?
ctrl = $controller('myController');
ctrl = element.controller('myController');
}));
it('should add some class', function () {
var button = $(element).find('#button')[0];
$(button).trigger('click');
var someElement = $(element).find('#idOfSomeElement')[0];
expect(someElement).toHaveSomeClass();
});
});
如何正确测试这种控制器? 而且我知道在控制器内部操作 DOM 是一件坏事,但我需要对其进行单元测试。
谢谢
【问题讨论】:
-
测试中的 DOM 固定装置与文档分离,因此
$('#idOfSomeElement')选择器不会到达固定装置。你最好的办法是模拟$(...)(很可能可以通过存根jQueryinit方法来完成,就像它显示的here)和addClass方法并监视他们的调用。这就是为什么将 jQuery 与 Angular 混合是一件坏事的原因之一。是的,这不应该在控制器中完成。
标签: angularjs unit-testing compilation controller ng-controller