如何单独测试控制器?

How to test controller separately?

我有一个控制器可以从不同的地方改变一些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 这是一件坏事,但我需要对其进行单元测试。

谢谢

我想你忘了将 angular.element 的 return 值分配给你的元素 属性...

element = angular.element(....

完成前每个:

beforeEach(inject(function ($rootScope, $compile) {
    var scope = $rootScope.$new();
    element = 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');

}));