Jasmine tests AngularJS Directives with templateUrl

前端 未结 8 612
执笔经年
执笔经年 2020-12-07 12:54

I\'m writing directive tests for AngularJS with Jasmine, and using templateUrl with them: https://gist.github.com/tanepiper/62bd10125e8408def5cc

However, when I run

相关标签:
8条回答
  • 2020-12-07 13:25

    As requested, converting a comment to an answer.


    For the people who want to make use of @Lior's answer in Yeoman apps:

    Sometimes the way the templates are referenced in karma config and consequently - the names of modules produced by ng-html2js don't match the values specified as templateUrls in directive definitions.
    You will need adjusting generated module names to match templateUrls.
    These might be helpful:

    • https://github.com/karma-runner/karma-ng-html2js-preprocessor#configuration
    • gist: https://gist.github.com/vucalur/7238489
    0 讨论(0)
  • 2020-12-07 13:40

    this is example how to test directive that use partial as a templateUrl

    describe('with directive', function(){
      var scope,
        compile,
        element;
    
      beforeEach(module('myApp'));//myApp module
    
      beforeEach(inject(function($rootScope, $compile, $templateCache){
       scope = $rootScope.$new();
       compile = $compile;
    
       $templateCache.put('view/url.html',
         '<ul><li>{{ foo }}</li>' +
         '<li>{{ bar }}</li>' +
         '<li>{{ baz }}</li>' +
         '</ul>');
       scope.template = {
         url: 'view/url.html'
        };
    
       scope.foo = 'foo';
       scope.bar = 'bar';
       scope.baz = 'baz';
       scope.$digest();
    
       element = compile(angular.element(
        '<section>' +
          '<div ng-include="template.url" with="{foo : foo, bar : bar, baz : baz}"></div>' +
          '<div ng-include="template.url" with=""></div>' +
        '</section>'
         ))(scope);
       scope.$digest();
    
     }));
    
      it('should copy scope parameters to ngInclude partial', function(){
        var isolateScope = element.find('div').eq(0).scope();
        expect(isolateScope.foo).toBeDefined();
        expect(isolateScope.bar).toBeDefined();
        expect(isolateScope.baz).toBeDefined();
      })
    });
    
    0 讨论(0)
  • 2020-12-07 13:41

    the Karma way is to load the template html dynamically into $templateCache. you could just use html2js karma pre-processor, as explained here

    this boils down to adding templates '.html' to your files in the conf.js file as well preprocessors = { '.html': 'html2js' };

    and use

    beforeEach(module('..'));
    
    beforeEach(module('...html', '...html'));
    

    into your js testing file

    0 讨论(0)
  • 2020-12-07 13:42

    If you're using ngMockE2E or ngMock:

    all HTTP requests are processed locally using rules you specify and none are passed to the server. Since templates are requested via HTTP, they too are processed locally. Since you did not specify anything to do when your app tries to connect to views/currency-select.html, it tells you it doesn't know how to handle it. You can easily tell ngMockE2E to pass along your template request:

    $httpBackend.whenGET('views/currency-select.html').passThrough();
    

    Remember that you can also use regular expressions in your routing paths to pass through all templates if you'd like.

    The docs discuss this in more detail: http://docs.angularjs.org/api/ngMockE2E.$httpBackend

    Otherwise use this:

    You'll need to use the $injector to access the new backend. From the linked docs:

    var $httpBackend;
    beforeEach(inject(function($injector) {
      $httpBackend = $injector.get('$httpBackend');
      $httpBackend.whenGET('views/currency-select.html').respond(200, '');
    }));
    
    0 讨论(0)
  • 2020-12-07 13:42

    You could perhaps get the $templatecache from the injector and then do something like

    $templateCache.put("views/currency-select.html","<div.....>");
    

    where in place of <div.....> you would be putting your template.

    After that you setup your directive and it should work just fine!

    0 讨论(0)
  • 2020-12-07 13:44

    If this is a unit-test, you won't have access to $httpBackend.passthrough(). That's only available in ngMock2E2, for end-to-end testing. I agree with the answers involving ng-html2js (used to be named html2js) but I would like to expand on them to provide a full solution here.

    To render your directive, Angular uses $http.get() to fetch your template from templateUrl. Because this is unit-testing and angular-mocks is loaded, angular-mocks intercepts the call to $http.get() and give you the Unexpected request: GET error. You can try to find ways to by pass this, but it's much simpler to just use angular's $templateCache to preload your templates. This way, $http.get() won't even be an issue.

    That's what the ng-html2js preprocessor do for you. To put it to work, first install it:

    $ npm install karma-ng-html2js-preprocessor --save-dev
    

    Then configure it by adding/updating the following fields in your karma.conf.js

    {
        files: [
          //
          // all your other files
          //
    
          //your htmp templates, assuming they're all under the templates dir
          'templates/**/*.html'
        ],
    
        preprocessors: {
            //
            // your other preprocessors
            //
    
            //
            // tell karma to use the ng-html2js preprocessor
            "templates/**/*.html": "ng-html2js"
        },
    
        ngHtml2JsPreprocessor: {
            //
            // Make up a module name to contain your templates.
            // We will use this name in the jasmine test code.
            // For advanced configs, see https://github.com/karma-runner/karma-ng-html2js-preprocessor
            moduleName: 'test-templates',
        }
    }
    

    Finally, in your test code, use the test-templates module that you've just created. Just add test-templates to the module call that you typically make in beforeEach, like this:

    beforeEach(module('myapp', 'test-templates'));
    

    It should be smooth sailing from here on out. For a more in depth look at this and other directive testing scenarios, check out this post

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