読者です 読者をやめる 読者になる 読者になる

AngularJSのカステムディレクティブで別のディレクティブをrequireしている場合のテストの書き方

前の記事のでいえばchildItemディレクティブのテストの書き方

コード再掲

#parentChild.coffee


"use strict"

#parent
#controller

angular.module("myApp")
.controller("ParentItemCtrl", ($scope, Child) ->
  #.......
  @removeChildItem = (childId, index)->
    Child.destroy({childId: childId}, ->
      $scope.parent.cildren.splice(index, 1)
    )
)

#parent directive

angular.module("myApp")
.directive("parentItem", ->
  restrict: "EA"
  templateUrl: "templates/parent_item.html"
  controller: "ParentItemCtrl"
  scope:
    parent: "=item"
)

#child directive

angular.module("myApp")
.directive("childItem", ($modal)->
  restrict: "EA"
  templateUrl: "templates/child_item.html"
  require: "^parentItem"
  scope:
    child: "=item"
  link: (scope, element, attrs, parentItemCtrl) ->
    scope.open = ()->
      modalInstance = $modal.open({
        templateUrl: "/remplates/modal_confirm.html"
      })

      modalInstance.result.then(->
        parentItemCtrl.removeChildItem(scope.child.id, scope.$index) 
      )
)

こんな感じでテストを書いた

#child_item_spec.coffee
"use strict"

describe "Directive: childItem", ->

  beforeEach module "myApp", "test.templates"

  scope = {}

  beforeEach inject ($controller, $rootScope) ->
    scope = $rootScope.$new()

  it "テンプレートに所定のデータが表示されること", inject ($compile) ->
    scope.child = {
      "id": 406
      "content": "child4"
      "created_at": "2014-09-23T11:16:23.609+09:00"
      "user":
        "id": 5018
        "profile":
          "name": "あい うえお"
    }
    element = angular.element '''<child-item item="child"></child-item>'''
    parentItemController = {
      removeChildItem: -> return
    }
    spyOn(parentItemController, "removeChildItem").andCallThrough()
    element.data("$parentItemController", parentItemController)
    element = $compile(element)(scope)
    childItemScope = element.find("child-item").scope()
    scope.$digest()
    expect(element.find(".child-user-name").text()).toEqual "あい うえお"

ChromeのDeveloper Toolsで確認するとわかるが、'$' + ディレクティブの名前 + 'Controller'という名前でcontrollerを取得しているので、それにあわせてmockを用意してあげればOK.
ちなみにディレクティブのhtmlは$templateCacheを使っていて、beforeEach module "myApp", "test.templates"の部分で、テスト用にテンプレートをJSにまとめたものを読み込んでいる。こちらについては別のエントリに書く。→書いた

参考