westandy
westandy

Reputation: 1440

Basic Karma Angular 1.5 Component Test

I am not sure if what I am doing is completely wrong, but when I switched from "directive" to "components" for defining a few of my HTML elements, I suddenly broke all of my Karma tests. here's what I have:

karam.conf.js

...
preprocessors: {
    'module-a/module-a.view.html': ['ng-html2js'],
    ...,
    'module-z/module-z.view.html': ['ng-html2js']
},

ngHtml2JsPreprocessor: {
    moduleName: 'theTemplates'
},
...

module-a.component.js

(function(){
    "use strict";

    angular.module('ModuleA').component('moduleAComponent',{
        controller: 'ModuleAController as moduleAVm',
        templateUrl: 'module-a/module-a.view.html'      
    });
})();

module-a-tests.js

"use strict";

describe('ModuleA',function(){

    beforeEach(module('ModuleA'));

    describe('Controller',function(){
        ...
    });

    describe('Component',function(){
        var element, $rootScope;
        beforeEach(module('theTemplates'));
        beforeEach(inject([
            '$compile','$rootScope',
            function($c,$rs) {
               $rootScope = $rs;
               element = $c('<module-a-component></module-a-component>')($rootScope);
               $rootScope.$digest(); // ???
            }
        ]));

        it('should have moduleAVm',function(){
            expect(element.html()).not.toBe(''); // FAILS HERE
            expect(element.html()).toContain('moduleVm'); // FAILS HERE TOO
        });

    });

});

The Error:

Expected '' not to be ''.

Upvotes: 1

Views: 1328

Answers (1)

westandy
westandy

Reputation: 1440

OK, after reading Angular's documentation more thoroughly, I came across this statement:

The easiest way to unit-test a component controller is by using the $componentController that is included in ngMock. The advantage of this method is that you do not have to create any DOM elements. The following example shows how to do this for the heroDetail component from above.

And it dawned on me, my describe('Controller',function(){...}); was what I really needed to change, and that I should just get rid of the 'Component' portion, formally known as 'Directive'

Here's my 'Controller' now:

    beforeEach(inject([
        '$componentController', // replaced $controller with $componentController
        function($ctrl){
            ctrl = $ctrl('queryResults',{ // Use component name, instead of controller name
                SomeFactory:MockSomeFactory,
                SomeService:MockSomeService
            });
        }
    ]));

Now, I still get to test my controller, while simultaneously testing the component. And I no longer have to create DOM elements using $compile, $rootScope, etc.

Upvotes: 4

Related Questions