angularjskarmaunit test

controllerAs仕様のcontrollerをユニットテストするための小ネタ

January 13, 2015

2 min read

mitsuruogMitsuru Ogawa

小ネタです。
いつも angular の controller を使うときはui-routerからcontrollerAsして使うことが多いですが、 controllerAs 仕様にした controller をユニットテストする際、少しハマったのでそのあたりを紹介します。

テストコードは angular 本家のPhoneCat チュートリアルのものを利用します。

controllerAs仕様にカスタムした controller

contorller.js

(function () {
  "use strict";

  angular.module("phonecatApp").controller("PhoneListCtrl", PhoneListCtrl);

  function PhoneListCtrl() {
    var vm = this;
    vm.phones = [
      {
        name: "Nexus S",
        snippet: "Fast just got faster with Nexus S.",
        age: 1,
      },
      {
        name: "Motorola XOOM™ with Wi-Fi",
        snippet: "The Next, Next Generation tablet.",
        age: 3,
      },
      {
        name: "MOTOROLA XOOM™",
        snippet: "The Next, Next Generation tablet.",
        age: 2,
      },
    ];
  }
})();

こちらがテストコード。

controllersSpec.js

"use strict";

describe("Controller: PhoneListCtrl", function () {
  // load the controller's module
  beforeEach(module("phonecatApp"));

  var MainCtrl, scope;

  // Initialize the controller and a mock scope
  beforeEach(inject(function ($controller, $rootScope) {
    MainCtrl = $controller("PhoneListCtrl as vm", {
      $scope: scope,
    });
  }));

  it("phoneモデルが3つ作成されていること", function () {
    expect(scope.vm.phones.length).toBe(3);
  });
});

$controllerで指定する controller の constructor 指定の部分にas構文が使えるんですね。知りませんでした。
$controller でテストする controller を inject したら、scope に設定した model などはasで指定した alias(今回だと vm)から参照できるみたい。

ちなみに、constructor でas構文を使わないとexpectするところでundefinedになります。

TypeError: 'undefined' is not an object (evaluating 'scope.phones.length')