AngularJS - 带有外部模板的单元测试指令

时间:2015-12-10 17:29:57

标签: javascript angularjs unit-testing

我正在使用npm模块karma-ng-html2js-preprocessor来执行此操作。

我的spec文件是:

describe('Directive: aGreatEye (external)', function() {
    var elm, scope;

    beforeEach(module('my-thing.template.html'));
    beforeEach(module('templates'));

    beforeEach(inject(function($rootScope, $compile) {

        elm = angular.element('<a-great-eye></a-great-eye>');
        scope = $rootScope;
        $compile(elm)(scope);
        scope.$digest();
    }));

    it('should do first directive unit test properly', function() {
        // assertions here
    });
});

然而我的错误是Error: [$injector:modulerr] Failed to instantiate module my-thing.template.html due to: Error: [$injector:nomod] Module 'my-thing.template.html' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.

尽管basePath文件的karma.config.js所在的网址是正确的。

这是我的 karma.config.js 文件:

module.exports = function (config) {

    // VIEW ONLINE AT: MAIN_ROOT/tests/jasmineReport/
    // You can either run via WebStorm or go online to do tests

    config.set({
        basePath: '.',
        frameworks: ['jasmine'],
        files: [
            // Vendor Files
            'bower_components/angular/angular.js',
            'bower_components/angular-mocks/angular-mocks.js',
            'bower_components/angular-ui-router/release/angular-ui-router.js',
            'bower_components/angular-filter/dist/angular-filter.js',
            'bower_components/angular-sanitize/angular-sanitize.js',
            'bower_components/lodash/lodash.min.js',

            // App-Specific Files
            'app/index.js',
            'app/common/models/*.js',
            'app/common/directives/*.js',
            'app/common/filters/*.js',
            'app/main/main.js',

            // App-Specific HTML Templates
            '*.html',
            '*.html.ext',

            // Test-Specific Files
            'tests/mock/**/*.js'
        ],
        exclude: [],
        preprocessors: {

            // HTML to JavaScript Preprocessors for
            // AngularJS Template Directives
            '*.html': ['ng-html2js']

        },
        port: 9876,
        colors: true,
        logLevel: config.LOG_INFO,
        autoWatch: true,
        browsers: ['PhantomJS'],
        singleRun: true,
        concurrency: Infinity,

        // NgHTML 2 JS Pre-Processor - OPTIONS
        ngHtml2JsPreprocessor: {
            stripPrefix: 'public/',
            stripSuffix: '.ext',
            prependPrefix: 'served/',
            moduleName: "templates"
        }
    })
};

我做错了什么?

1 个答案:

答案 0 :(得分:1)

这些是我对我的指令的测试,他们测试模板是否被正确调用并正确阐述:

'use strict';

/**
* @author Gianmarco Laggia
* 
* Test suite for menu directive
*/
describe('Menu Widget Directive Rendering', function () {

    beforeEach(module('myModule'));

    var compile, mockBackend, rootScope;

    // Step 1 - Get the $compile service injected into our test
    beforeEach(inject(function ($compile, $httpBackend, $rootScope) {
        compile = $compile;
        mockBackend = $httpBackend;
        rootScope = $rootScope;
    }));


    it('should render HTML based on scope correctly', function () {
        var scope = rootScope.$new();

        mockBackend.expectGET('views/directives/menu.html').respond(
            '<div class="menu">' +
            '<ul>' +
            '<li><a href="#/" class="waves-effect waves-light">HOME</a></li>' +
            '<li><a href="#/activities" class="waves-effect waves-light">ATTIVIT</a></li>' +
            '<li><a href="#/people" class="waves-effect waves-light">PERSONE</a></li>' +
            '<li><a href="#/locations" class="waves-effect waves-light">LUOGHI</a></li>' +
            '<div class="clear-both"></div>' +
            '</ul>' +
            '</div>');

        //Step 4
        var element = compile('<menu></menu>')(scope);

        //Step 5
        scope.$digest();
        mockBackend.flush();

        //Step 6
        expect(element.html()).toEqual(
            '<div class="menu">' +
            '<ul>' +
            '<li><a href="#/" class="waves-effect waves-light">HOME</a></li>' +
            '<li><a href="#/activities" class="waves-effect waves-light">ATTIVIT</a></li>' +
            '<li><a href="#/people" class="waves-effect waves-light">PERSONE</a></li>' +
            '<li><a href="#/locations" class="waves-effect waves-light">LUOGHI</a></li>' +
            '<div class="clear-both"></div>' +
            '</ul>' +
            '</div>'
        );
        mockBackend.verifyNoOutstandingExpectation();
    });

    it('should not render HTML is used not as element 1', function () {
        //Step 2 - Set up our directive instance HTML
        var scope = rootScope.$new();

        //Step 4
        var element = compile('<div menu></div>')(scope);

        //Step 5
        scope.$digest();

        //Step 6
        expect(element.html()).toEqual('');
        mockBackend.verifyNoOutstandingRequest();
    });

    it('should not render HTML is used not as element 2', function () {
        //Step 2 - Set up our directive instance HTML
        var scope = rootScope.$new();

        //Step 4
        var element = compile('<div class="menu"></div>')(scope);

        //Step 5
        scope.$digest();

        //Step 6
        expect(element.html()).toEqual('');
        mockBackend.verifyNoOutstandingRequest();
    });

    it('should not render HTML is used not as element 3', function () {
        //Step 2 - Set up our directive instance HTML
        var scope = rootScope.$new();

        //Step 4
        var element = compile('<!-- directive: menu -->')(scope);

        //Step 5
        scope.$digest();

        //Step 6
        expect(element.html()).toBeUndefined();
        mockBackend.verifyNoOutstandingRequest();
    });
});

此测试由于其限制而仅使用<menu></menu>调用该指令

/**
* @author Gianmarco Laggia
*
* Menu directive, used to handle a menu based on the actual $location.path
*/
angular.module('myModule')
    .directive('menu', ['Page', function (Page) {
        return {
            restrict: 'E',
            scope: true,
            templateUrl: 'views/directives/menu.html',
            link: function ($scope, $element, $attrs) {
                $scope.isCurrentPage = function (page) {
                    return Page.getActualPage() == page;
                };
            }
        };
}]);