web-dev-qa-db-ja.com

JasmineはtemplateUrlでAngularJSディレクティブをテストします

JasmineでAngularJSのディレクティブテストを作成し、それらでtemplateUrlを使用しています: https://Gist.github.com/tanepiper/62bd10125e8408def5cc

ただし、テストを実行すると、Gistに含まれるエラーが表示されます。

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

私がドキュメントで読んだことから、私はこれを正しくやっていたと思ったが、そうは思えない-ここで何が欠けているのか?

ありがとう

70
Tane Piper

NgMockE2EまたはngMockを使用している場合:

allHTTP要求は指定したルールを使用してローカルで処理され、noneは渡されますサーバーに。テンプレートは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, '');
}));
70

karmaの方法は、テンプレートhtmlを$ templateCacheに動的にロードすることです。説明したように、html2jsカルマプリプロセッサを使用できます here

これは、テンプレート '。html'をconf.jsファイル内のファイルに追加することと、プリプロセッサー= {'。html': 'html2js' };

そして使用する

beforeEach(module('..'));

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

あなたのjsテストファイルに

20
Lior

これが単体テストの場合、$httpBackend.passthrough()にアクセスできません。これは、エンドツーエンドのテスト用にngMock2E2でのみ利用可能です。 ng-html2js(以前はhtml2jsという名前でした)に関連する回答に同意しますが、ここで完全なソリューションを提供するためにそれらを拡張したいと思います。

ディレクティブをレンダリングするには、Angularは$http.get()を使用してtemplateUrlからテンプレートを取得します。これは単体テストであり、angular-mocksがロードされるため、angular-mocks$http.get()そしてUnexpected request: GETエラーが表示されます。これをパスする方法を見つけることはできますが、テンプレートのプリロードに角度の$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モジュールを使用します。次のように、通常beforeEachで行うモジュール呼び出しにtest-templatesを追加するだけです。

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

これからは順調に航行するはずです。このシナリオおよび他のディレクティブテストシナリオの詳細については、 this post をご覧ください。

6

おそらく、インジェクターから$templatecacheを取得してから、次のようなことを行うことができます

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

<div.....>の代わりに、テンプレートを配置します。

その後、ディレクティブを設定すると、うまく機能するはずです!

5
ganaraj

要求に応じて、コメントを回答に変換します。


Yeomanアプリで@Liorの回答を利用したい人向け:

場合によっては、karma configでテンプレートが参照される方法、およびng-html2jsによって生成されるモジュールの名前は、ディレクティブ定義でtemplateUrlsとして指定された値と一致しません。
templateUrlsと一致するように、生成されたモジュール名を調整する必要があります。
これらは役に立つかもしれません:

4
vucalur

それでも機能しない場合は、フィドラーを使用して、htmltojsプロセッサーによって動的に生成されたjsファイルの内容を確認し、テンプレートファイルのパスを確認します。

このようなものでなければなりません

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

私の場合、問題を引き起こしていた実際の指令とは異なりました。

TemplateURLをすべての場所でまったく同じにすることで、私は成功しました。

4
akshayswaroop

これは、partialを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();
  })
});
2
a8m

jasmine-maven-plugin をRequireJSと一緒に使用している場合、 text plugin を使用してテンプレートコンテンツを変数にロードし、テンプレートキャッシュに配置できます。


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

    });
});
0