我正在开发一个AngularJS应用程序。我希望能够通过这个应用程序实现单元测试。目前,我正在努力对我的一个指令进行单元测试。这时,我有一个模块设置如下:
angular.module('my.module', [])
.controller('myCtrl', function ($scope, $element) {
// Directive specific business logic goes here
})
.directive('myDirective', function() {
return {
restrict: 'E',
transclude: true,
replace: true,
scope: {
title:'=',
state:'@'
},
templateUrl: 'myHtml.tpl.html',
controller: myCtrl
};
})
;
我已将控制器从我的指令中分离出来,因为我需要能够对控制器进行单元测试。此代码适用于应用程序本身。但是,当我尝试对其进行单元测试时,我遇到了问题。我遇到问题,因为我无法弄清楚如何从单元测试中将$元素注入控制器。目前,我有以下测试设置:
describe('my.module', function () {
var $scope;
var myCtrl;
beforeEach(module('myApp'));
beforeEach(inject(function ($controller, $rootScope, $element) {
$scope = $rootScope.$new();
myCtrl = $controller('myCtrl', { $scope: $scope });
}));
it('should create controller', inject(function () {
expect(testCtrl).toBeDefined();
}));
it('should create the directive', inject(function ($rootScope, $compile, $log) {
var d = angular.element('<my-directive></my-directive>');
$compile(d)($rootScope);
$scope.$digest();
expect($log.assertEmpty).not.toThrow();
}));
});
$ element是自动注入指令的东西。但是,我无法弄清楚如何将其注入控制器。我需要这样做,所以我可以进行单元测试。我该怎么做?
谢谢!
答案 0 :(得分:2)
我可以在控制器的单元测试中推荐的只是担心控制器暴露的逻辑。您正试图在控制器测试中测试指令的逻辑,即通过$element
。
在控制器测试中模拟它,因为元素可以是任何东西。你的控制器不应该关心DOM;它是一个控制器,它的主要(也许只是)工作是创建一个范围并向范围公开“事物” - 函数,变量,逻辑。它们不应该与指令的逻辑绑定,否则耦合太紧。控制器应该能够自由地接收输入, 的正确输入,并使用输入来回馈输出。
如果您可以举例说明您的控制器公开的逻辑,那么我可以进一步帮助编写单元测试。
更新
现在查看您提供的单元测试。您需要将逻辑从控制器和指令的单元测试中分离出来。
答案 1 :(得分:1)
用于注入$element
和$log
按原样执行:
describe('my.module', function ($compile) {
var $scope, $controller, $element, $log, $compile, html;
beforeEach(module('myApp'));
// an another module ...
beforeEach(inject(function ($injector) {
$scope = $injector.get('$rootScope');
$controller = $injector.get('$controller');
$element = $injector.get('$element');
$log = $injector.get('$log');
$compile = $injector.get('$compile');
function createController (){
return $controller('MyCtrl', {'$scope' : $scope, '$element' : $element, '$log': $log });
}
// init your controller
createController();
}));
it('should create the directive',function () {
// possibility to use $scope, $element, $log in your test
$compile('<my-directive></my-directive>')($scope);
$scope.$digest();
expect($log.assertEmpty).not.toThrow();
});
});