Reputation: 113
I am trying to test a javascript file which has in it a controller and some HTML DOM elements which it interacts with.
The class under test is:
function BaseConceptMenu(options) {
var baseConceptMenu = new BaseMenu(options);
//Public function -->Method under Test
function showCodeConceptToolbar() {
var scope = angular.element('#toolbar').scope();
scope.$apply(function() {
scope.toolbarController.show(baseConceptMenu.someObject);
});
}
I am trying to mock the controller and create the HTML DOM element "toolbar" on the fly without trying to create an external HTML template just for the sake of testing.
I am trying to create the div "toolbar" inside the before each and mocking the "CodeConceptToolbarController" controller
beforeEach(inject(function ($rootScope, $compile) {
elm = document.createElement('div');
elm.id = 'toolbar';
scope = $rootScope.$new();
createController = function() {
return $controller('CodeConceptToolbarController', {
$scope: scope
});
};
$compile(elm)(scope);
scope.$digest();
}));
However when I try to test it as below
it('Test Code ConeptToolbarContoller', function() {
// var toolbar = angular.element('#toolbar');
document.getElementById("toolbar").scope().toolbarController = createController();
//As of now,not doing any-idepth testing
//Just a base test call
var menu = new BaseConceptMenu({});
expect(menu.show()).toBe(true);
});
I get this error
TypeError: Cannot read property 'scope' of null
Could anyone provide a way to test this? or is there a better way to test this? currently I am using Maven-jasmine plugin
Upvotes: 0
Views: 827
Reputation: 4623
Two problems:
As per https://developer.mozilla.org/en-US/docs/Web/API/document.getElementById, "Elements not in the document are not searched by getElementById." $compile doesn't insert the element into the DOM - it just sets up appropriate bindings (and does smart things like handling nested directives inside your template string). Your getElementById will fail to find a match. You need to insert the element into the DOM somewhere.
getElementById returns a raw HTML DOM element. To get the Angular scope from it, the docs call for wrapping it in angular.element():
var element = document.getElementById(id);
angular.element(element).scope()...
This pattern will provide the Angular wrapper around the element to do the rest of the magic. It's all based on jqLite, which isn't jQuery but does follow a lot of the same patterns. For those used to jQuery, think of it like writing $(element)
.
Upvotes: 0