IT TIP

Jasmine은 templateUrl을 사용하여 AngularJS 지시문을 테스트합니다.

itqueen 2020. 11. 1. 19:06
반응형

Jasmine은 templateUrl을 사용하여 AngularJS 지시문을 테스트합니다.


Jasmine으로 AngularJS에 대한 지시문 테스트를 작성하고 템플릿 Url을 사용하고 있습니다 : https://gist.github.com/tanepiper/62bd10125e8408def5cc

그러나 테스트를 실행하면 요점에 오류가 포함됩니다.

Error: Unexpected request: GET views/currency-select.html

문서에서 읽은 내용에서이 작업을 올바르게 수행하고 있다고 생각했지만 그렇지 않은 것 같습니다. 여기서 무엇을 놓치고 있습니까?

감사


ngMockE2E 또는 ngMock을 사용하는 경우 :

모든 HTTP 요청은 지정한 규칙을 사용하여 로컬로 처리되며 서버로 전달되는 것은 없습니다 . 템플릿은 HTTP를 통해 요청되기 때문에 로컬에서도 처리됩니다. 앱이에 연결을 시도 할 때 수행 할 작업을 지정하지 않았으므로 views/currency-select.html처리 방법을 모른다고 알려줍니다. ngMockE2E에게 템플릿 요청을 전달하도록 쉽게 지시 할 수 있습니다.

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

원하는 경우 라우팅 경로에서 정규식을 사용하여 모든 템플릿을 전달할 수도 있습니다.

문서에서는 이에 대해 자세히 설명합니다. http://docs.angularjs.org/api/ngMockE2E.$httpBackend

그렇지 않으면 다음을 사용하십시오.

$injector새 백엔드에 액세스하려면를 사용해야합니다 . 링크 된 문서에서 :

var $httpBackend;
beforeEach(inject(function($injector) {
  $httpBackend = $injector.get('$httpBackend');
  $httpBackend.whenGET('views/currency-select.html').respond(200, '');
}));

Karma 방식은 템플릿 html을 $ templateCache에 동적으로로드하는 것입니다. 여기에 설명 된대로 html2js karma 전처리기를 사용할 수 있습니다.

이는 conf.js 파일의 파일에 ' .html' 템플릿을 추가하는 것으로 귀결됩니다. 전 처리기 = { ' .html': 'html2js'};

그리고 사용

beforeEach(module('..'));

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

js 테스트 파일에


단위 테스트 인 경우에 액세스 할 수 없습니다 $httpBackend.passthrough(). 종단 간 테스트를 위해 ngMock2E2에서만 사용할 수 있습니다. ng-html2js(예전에는 html2js로 명명 됨) 관련 답변에 동의 하지만 여기에서 전체 솔루션을 제공하기 위해 확장하고 싶습니다.

당신의 지시를 렌더링하려면, 각도 용도 $http.get()에서 템플릿을 가져올 수 있습니다 templateUrl. 이것은 단위 테스트이고 angular-mocks로드 되기 때문에 angular-mocks는 호출을 가로 채서 오류를 $http.get()제공합니다 Unexpected request: GET. 이를 전달하는 방법을 찾을 수 있지만 angular를 사용 $templateCache하여 템플릿을 미리로드 하는 것이 훨씬 간단합니다 . 이렇게 $http.get()하면 문제가되지 않습니다.

그것이 ng-html2js 전처리 기가 당신을 위해하는 일입니다. 작동하려면 먼저 설치하십시오.

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

그런 다음 다음 필드를 추가 / 업데이트하여 구성하십시오. 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',
    }
}

마지막으로 테스트 코드에서 test-templates방금 만든 모듈을 사용합니다 . 다음 과 같이 test-templates에서 일반적으로 수행하는 모듈 호출에 추가 하기 만하면 됩니다 beforeEach.

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

여기서부터는 순조로운 항해가 될 것입니다. 이 및 기타 지침 테스트 시나리오에 대한 자세한 내용은 이 게시물을 확인하십시오.


아마도 $templatecache인젝터에서 얻은 다음 다음과 같이 할 수 있습니다.

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

대신 <div.....>템플릿을 넣을 수 있습니다.

그 후 지시문을 설정하면 잘 작동합니다!


그래도 작동하지 않으면 fiddler를 사용하여 htmltojs 프로세서에서 동적으로 생성 한 js 파일의 내용을보고 템플릿 파일의 경로를 확인하십시오.

다음과 같아야합니다

angular.module('app/templates/yourtemplate.html', []).run(function($templateCache) {
  $templateCache.put('app/templates/yourtemplate.html', 

제 경우에는 문제를 일으킨 실제 지시문과 동일하지 않았습니다.

모든 장소에서 정확히 동일한 templateURL을 사용하면 통과했습니다.


요청에 따라 댓글을 답변으로 변환합니다.


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:


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();
  })
});

If you are using the jasmine-maven-plugin together with RequireJS you can use the text plugin to load the template content into a variable and then put it in the template cache.


define(['angular', 'text!path/to/template.html', 'angular-route', 'angular-mocks'], function(ng, directiveTemplate) {
    "use strict";

    describe('Directive TestSuite', function () {

        beforeEach(inject(function( $templateCache) {
            $templateCache.put("path/to/template.html", directiveTemplate);
        }));

    });
});

참고URL : https://stackoverflow.com/questions/14761045/jasmine-tests-angularjs-directives-with-templateurl

반응형