web-dev-qa-db-ja.com

AngularJSでコントローラーを定義するディレクティブの単体テスト

KarmaとJasmineを使用して、いくつかのことを行うディレクティブをテストしようとしています。 1つ目はtemplateUrlを使用し、2つ目はコントローラーを定義することです。これは正しい用語ではないかもしれませんが、宣言でコントローラーを作成します。 Angularアプリケーションは、各ユニットが独自のモジュールに含まれるように設定されています。たとえば、すべてのディレクティブはモジュールapp.directiveに含まれ、すべてのコントローラーはapp.controllerに含まれ、すべてサービスはapp.serviceなどに含まれています。

さらに複雑なことに、このディレクティブ内で定義されているコントローラーには単一の依存関係があり、$スコープに値を設定するための$ http要求を行う関数が含まれています。 $ httpBackendモックを使用してこの依存関係をモックして$ http呼び出しをシミュレートし、この関数の呼び出しに適切なオブジェクトを返すことができることを知っています。私が作成した他の単体テストでこれを何度も実行し、この概念をかなりよく理解しています。

以下のコードはCoffeeScriptで書かれています。

これが私の指示です:

    angular.module('app.directive')
      .directive 'exampleDirective', [() ->
        restrict: 'A'
        templateUrl: 'partials/view.html'
        scope: true
        controller: ['$scope', 'Service', ($scope, Service) ->
          $scope.model = {}
          $scope.model.value_one = 1

          # Call the dependency
          Service.getValue()
            .success (data) ->
              $scope.model.value_two = data
            .error ->
              $scope.model.value_two = 0
        ]
      ]

これが依存関係サービスです:

    angular.module("app.service")
      .factory 'Service', ['$http', ($http) ->

      getValue: () ->
        options.method = "GET"
        options.url = "example/fetch"

        $http _.defaults(options)

ここにビューがあります:

    <div>
      {{model.value_one}} {{model.value_two}}
    </div>

私の目標はこれを配線する方法を理解することだけなので、これをかなり単純化しました。そこからそれを取ることができます。私がこのように構成している理由は、最初にこれを作成しなかったためです。私は既存のプロジェクトのテストの作成に取り組んでいますが、他の方法でそれを構成することはできません。テストを書き込もうとしましたが、やりたいことができません。

値がビューにバインドされているかどうかをテストし、可能であれば、コントローラーが値を正しく作成しているかどうかもテストしたいと思います。

これが私が持っているものです:

    'use strict'

    describe "the exampleDirective Directive", ->

      beforeEach module("app.directive")
      beforeEach module("app/partials/view.html")

      ServiceMock = {
        getValue : () ->

        options.method = "GET"
        options.url = "example/fetch"

        $http _.defaults(options)
      }

     #use the mock instead of the service
     beforeEach module ($provide) ->
       $provide.value "Service", ServiceMock
       return

     $httpBackend = null
     scope = null
     elem = null

     beforeEach inject ($compile, $rootScope, $injector) ->

     # get httpBackend object
     $httpBackend = $injector.get("$httpBackend")
     $httpBackend.whenGET("example/fetch").respond(200, "it works")

     #set up the scope
     scope = $rootScope

     #create and compile directive
     elem = angular.element('<example-directive></example-directive>')
     $compile(elem)(scope)
     scope.$digest()

私は自分がどれだけ近いか、あるいはこれが正しいかどうかさえわかりません。値がビューに正しくバインドされていることを表明できるようにしたい。 Vojtajinaの例を使用して、karma.jsファイルにhtml2jsを設定し、ビューを取得できるようにしました。私は答えを見つけるために多くの研究をしました、しかし私はいくつかの助けが必要です。うまくいけば、私が正しい方向に私を向けることができるよりも賢いプログラマーです。ありがとうございました。

18
The Zuidz

カルマで要素を作成してから、 .controller() 関数をディレクティブの名前とともに使用してコントローラーを取得します。あなたの例では、最後の数行を次のように置き換えます。

_elem = angular.element('<div example-directive></div>');
$compile(elem)($rootScope);
var controller = elem.controller('exampleDirective');
_

ディレクティブをどのように定義したかを考えると、それは要素としてではなく、属性ごとでなければならないことに注意してください。また、100%確信はありませんが、_scope.$digest;_は必要ないと思います。通常、適用する必要があるものはすべてscope.$apply(function() {})ブロックに入れます。

30
user2680223