LoginSignup
62
61

More than 5 years have passed since last update.

AngularJSの単体テストを書く

Posted at

Jasmine を使って AngularJS の単体テストコードを書く。

コントローラとかを個別の関数として定義している場合

フォルダ構成
|-test.html      : テストを動かすための html.
|-controllers.js : コントローラを定義した js.
|-app.js         : AngularJS の設定をしている js.
|-test.js        : Jasmine のテストコード.
|-jasmine/       : Jasmine のファイル類.
`-angular/       : AngularJS のファイル類.
controllers.js
var mine = {
    controllers: {
        SampleController: function($scope) {
            $scope.message = 'Hello SampleController!!';

            $scope.click = function() {
                $scope.message = 'clicked!!';
            };
        }
    }
};
app.js
angular
.module('mine', [])
.controller('SampleController', mine.controllers.SampleController);
test.js
describe('suite', function() {
    var controller,
        $scope;

    beforeEach(function() {
        $scope = {};
        controller = new mine.controllers.SampleController($scope);
    });

    it('spec', function() {
        expect($scope.message).toBe('Hello SampleController!!');

        $scope.click();

        expect($scope.message).toBe('clicked!!');
    });
});
test.html
<!doctype html>
<html>
  <head>
    <link href="jasmine/jasmine.css" rel="stylesheet"/>
    <script src="jasmine/jasmine.js"></script>
    <script src="jasmine/jasmine-html.js"></script>
    <script src="jasmine/boot.js"></script>
    <script src="jasmine/console.js"></script>

    <script src="angular/angular.min.js"></script>

    <script src="controllers.js"></script>
    <script src="app.js"></script>
    <script src="test.js"></script>
  </head>
  <body>
  </body>
</html>
  • 普通にコントローラをインスタンス化して、スタブの $scope を渡してテストしている。
  • 必要に応じて Jasmine のスパイ機能とかを使えばいい気がする。

コントローラとかを個別の関数として定義していない場合

フォルダ構成
|-test.html      : テストを動かすための html.
|-app.js         : AngularJS の設定をしている js. コントローラの定義もまとめている.
|-test.js        : Jasmine のテストコード.
|-jasmine/       : Jasmine のファイル類.
`-angular/       : AngularJS のファイル類.
app.js
angular
.module('mine', [])
.controller('SampleController', function($scope) {
    $scope.message = 'Hello SampleController!!';

    $scope.click = function() {
        $scope.message = 'clicked';
    };
});
test.js
describe('suite', function() {
    var controller, $scope;

    beforeEach(function() {
        module('mine');

        inject(function($rootScope, $controller) {
            $scope = $rootScope.$new();

            controller = $controller('SampleController', {
                $scope: $scope
            });
        });
    });

    it('spec', function() {
        expect($scope.message).toBe('Hello SampleController!!');

        $scope.click();

        expect($scope.message).toBe('clicked');
    });
});
test.html
<!doctype html>
<html>
  <head>
    <link href="jasmine/jasmine.css" rel="stylesheet"/>
    <script src="jasmine/jasmine.js"></script>
    <script src="jasmine/jasmine-html.js"></script>
    <script src="jasmine/boot.js"></script>
    <script src="jasmine/console.js"></script>

    <script src="angular/angular.min.js"></script>
    <script src="angular/angular-mocks.js"></script>

    <script src="app.js"></script>
    <script src="test.js"></script>
  </head>
  <body>
  </body>
</html>
  • angular.module().controller() を使って匿名関数でコントローラを定義しているケース。
  • mine モジュールからコントローラを取得する必要がある。
  • angular-mocks.js を使うことで、テストコード中でモジュール内の各インスタンスを取得できる。
  • module('mine'); で、 mine モジュールを読み込んでいる。
  • inject() に渡した関数内で必要なスコープやコントローラを取り出している。

参考

62
61
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
62
61