Reputation: 579
This error is occurring when I try to instantiate the setup phase of my unit test. I am unit testing a directive, which has its own controller. For best practice purposes I can always add the controllerAs
property to the directive to assign the controller a name, but I get the same error if I do that anyway.
describe('myDirective', function() {
beforeEach(module('app'));
beforeEach(module('app/directives/directive.html'));
var theArgs = {
arg1 : [],
arg2 : 'id',
arg3 : [],
arg4 : '',
arg5 : false
};
beforeEach(inject(function($templateCache, _$compile_, _$rootScope_, $controller) {
template = $templateCache.get('app/directives/directive.html');
$templateCache.put('app/directives/directive.html', template);
$compile = _$compile_;
$rootScope = _$rootScope_;
scope = $rootScope.$new();
scope.args = theArgs;
ctrl = $controller({
$scope: scope
});
}));
it('should compile', function() {
var myElement = angular.element('<div my-directive args="theArgs" ></div>');
var element = $compile(myElement)(scope);
// Grab scope. Depends on type of scope.
scope = element.isolateScope() || element.scope();
// Grab controller instance
controller = element.controller(ctrl);
$rootScope.$digest();
// Mock the directive's controller's add() function
scope.add();
});
});
The error is occurring within this block:
ctrl = $controller({
$scope: scope
});
Since the controller doesn't have a name, I am not passing it one in the above code block. That shouldn't throw an error by itself though, right? I don't think there is a problem with my karma configuration since my other 500 tests are all passing.
The second error is being thrown at controller = element.controller(ctrl);
, where it can't find the ctrl
variable. That error makes sense because it's caused by the first error, but I can't figure out how to fix the first error.
UPDATE: Added directive code to show how the controller was defined. It was never assigned a name, it is anonymous, and I didn't use the controllerAs property, because it returns an error.
app.directive('myDirective', function() {
var dirController = ['$scope', function($scope) {
$scope.add = function() { ... };
}];
return {
restrict: 'A',
scope: {
args: '='
},
templateUrl: '/path/to/template.html',
controller: dirController
};
});
Upvotes: 3
Views: 1021
Reputation: 1710
Well the problem is exactly with this code section:
ctrl = $controller({
$scope: scope
});
Since $controller
is require the name of the controller for the first parameter, and then the injectables afterwards within an object literal.
E.g.: Tell it which controller should it create:
ctrl = $controller('MyControllerName', {
$scope: scope
});
Upvotes: 1