How do I inject a mock dependency into an angular directive with Jasmine on Karma

前端 未结 1 1492
隐瞒了意图╮
隐瞒了意图╮ 2021-01-05 04:41

I have the following directive:

function TopLevelMenuDirective ($userDetails, $configuration) {
    return {
        restrict:\'A\',
        templateUrl: sta         


        
1条回答
  •  迷失自我
    2021-01-05 05:18

    To load the template file you must configure karma-ng-html2js-preprocessor in karma.

    First, visit this page and follow the installation instructions. Then, you need to add a couple of entries in your karma.config.js file:

    files: [
        'templates/*.html'
    ],
    

    this tells karma to load all html files in the templates folder (if your templates are somewhere else, put that folder there).

    preprocessors: { '**/*.html': 'ng-html2js' },
    

    this tells karma to pass all html files through the ng-html2js preprocessor, which then transforms them into angular modules that put the templates into the $templateCache service. This way, when $httpBackend queries the "server" for the template, it get's intercepted by the template cache and the correct html is returned. All fine here, except for the template's URL: it has to match the templateUrl property in the directive, and ng-html2js passes the full path as the uri by default. So we need to transform this value:

    ngHtml2JsPreprocessor: {
        cacheIdFromPath: function(filepath) {
    
            var matches = /^\/(.+\/)*(.+)\.(.+)$/.exec(filepath);
    
            return 'templates/' + matches[2] + '.' + matches[3];
        }
    },
    

    this receives filepath and passes it through a regular expression that extracts the path, file name and extension into an array. You then prepend 'templates/ to the file name and extension and you get the expected uri.

    After all this is done making the template available is a matter of loading the module before your test is run:

    beforeEach(module('templates/TopLevelMenu.Template.html'));
    

    keep in mind, module is an external service located in angular-mocks.js.

    for injecting a custom service into the directive you need to override the service's provider:

    beforeEach(module(function ($provide) {
        $provide.provider('$userDetails', function () { 
            this.$get = function () {
                return {
                    name: 'test name', 
                    gravatar: 'test avatar'
                };
            }
        });
    }));
    

    $provide is the service that provides your providers. So, if you want to inject a mock dependency you override the provider here.

    With that code executing before your test you'll have a mock $userDetails service that returns your predefined strings.

    0 讨论(0)
提交回复
热议问题