describe('indexController', function() {
/**
* 各テストの前に実行されるいわば初期化処理。
* `module`メソッドによって各テストから`coreApp`を利用できるようにする。
*/
beforeEach(function() {
module('coreApp');
});
/**
* 値が等しいかを確認
*/
it('spec1', inject(function($controller) {
// このラインでindexControllerの処理が走り、valueに値がセットされる
var controller = $controller('indexController');
// 値が等しいか確認する
expect(controller.value).toBe('hello world.');
}));
/**
* 特定のメソッドが実行されたかを確認
*/
it('spec2', inject(function($controller, indexService) {
// コントローラーの初期化前に監視対象のメソッドを登録
// 監視対象に登録されたメソッドは本来の挙動を示さなくなる
// よってログが吐かれない
spyOn(indexService, 'run');
var controller = $controller('indexController');
// 監視下においたメソッドが実行されているかどうか確認
expect(indexService.run).toHaveBeenCalled();
}));
/**
* 特定のメソッドが、指定した引数と共に実行されているか確認
*/
it('spec3', inject(function($controller, indexService) {
// 監視対象に登録
spyOn(indexService, 'run2');
var controller = $controller('indexController');
// 監視下においたメソッドが、指定した引数(順番)と共に実行されているかどうか確認
expect(indexService.run2).toHaveBeenCalledWith('hello', 'world.');
}));
/**
* 監視下においたメソッドでも本来の実装を実行させる
*/
it('spec4', inject(function($controller, indexService) {
// 監視対象に登録するが、本来の実装も実行したい場合
spyOn(indexService, 'run').and.callThrough();
spyOn(indexService, 'run2').and.callThrough();
var controller = $controller('indexController');
// 監視下においたメソッドが、指定した引数(順番)と共に実行されているかどうか確認
expect(indexService.run).toHaveBeenCalled();
expect(indexService.run2).toHaveBeenCalled();
}));
/**
* 監視下においたメソッドの返り値を強制的に指定する
*/
it('spec5', inject(function($controller, indexService) {
// 監視対象においた関数から本来返される値を上書きする
spyOn(indexService, 'run3').and.returnValue('bar');
var controller = $controller('indexController');
// 本来であれば'foo'が格納されているはずだが、強制的に'bar'に上書かれている
expect(controller.result).toBe('bar');
}));
/**
* 監視下においたメソッドの関数を上書きする
*/
it('spec6', inject(function($controller, indexService) {
// 監視対象においた関数を任意の関数と差し替える
spyOn(indexService, 'run3').and.callFake(function() {
return 'method is overrided!';
});
var controller = $controller('indexController');
// メソッドが上書かれ、返却値が変わっている
expect(controller.result).toBe('method is overrided!');
}));
/**
* 特定のメソッドが実行された場合に例外を投げる
*/
it('spec7', inject(function($controller, indexService) {
// 監視対象においた関数が実行された際に例外を投げる
// 叩かれたらエラーになってテストが停まるので、ここでは叩かれない関数を指定
spyOn(indexService, 'run4').and.throwError('run4() is called!');
var controller = $controller('indexController');
// こうすることで実際に叩かれた際に投げられるエラーメッセージが一致していなくてもアウトとなる
expect(indexService.run4).toThrowError('run4() is called!');
}));
/**
* 関数が実行された回数を確認する
*/
it('spec8', inject(function($controller, indexService) {
// 監視対象に置く
// 監視対象においているので、当然ログは吐かれない
// callFakeかcallThroughを用いることで本来の挙動になる
spyOn(indexService, 'run5');
var controller = $controller('indexController');
// 関数が実行された回数を確認する
expect(indexService.run5.calls.count()).toBe(100);
}));
/**
* 関数が実行された際の引数をキャプチャして確かめる
*/
it('spec9', inject(function($controller, indexService) {
// 監視対象に置く
spyOn(indexService, 'run6');
var controller = $controller('indexController');
// 関数が実行された回数を確認する
expect(indexService.run6.calls.count()).toBe(4);
// 関数が実行された際の引数をキャプチャする
expect(indexService.run6.calls.argsFor(0)).toEqual([]); // 1回目の実行時
expect(indexService.run6.calls.argsFor(1)).toEqual(['foo']); // 2回目の実行時
expect(indexService.run6.calls.argsFor(2)).toEqual(['foo', 'bar']); // 3回目の実行時
expect(indexService.run6.calls.argsFor(3)).toEqual(['foo', 'bar', 'baz']); // 4回目の実行時
}));
/**
* 関数が実行された際の情報を取得する
*/
it('spec10', inject(function($controller, indexService) {
// 監視対象に置く
spyOn(indexService, 'run5');
var controller = $controller('indexController');
// 関数が最初に実行された際の情報を取得
expect(indexService.run5.calls.first()).toEqual({args: [0], object: indexService, returnValue: undefined}); // 1回目の実行時
// 関数が最後に実行された際の情報を取得
expect(indexService.run5.calls.mostRecent()).toEqual({args: [99], object: indexService, returnValue: undefined}); // 最後の実行時
}));
/**
* 監視関数をその場で作成する
*/
it('spec11', inject(function($controller, indexService) {
// 監視関数を作る
var createdSpy = jasmine.createSpy();
// 作成した監視関数を実行
createdSpy();
// 実行されたか確認
expect(createdSpy).toHaveBeenCalled();
}));
/**
* 監視オブジェクトを作成する
*/
it('spec12', inject(function($controller, indexService) {
// 監視オブジェクトを作る
var createdSpyObject = jasmine.createSpyObj('objectName', ['method1', 'method2', 'method3']);
// 作成した監視オブジェクトの関数を実行
createdSpyObject.method1();
createdSpyObject.method3();
// 実行されたか確認
expect(createdSpyObject.method1).toHaveBeenCalled();
// 実行されていないか確認
expect(createdSpyObject.method2).not.toHaveBeenCalled();
// 実行されたか確認
expect(createdSpyObject.method3).toHaveBeenCalled();
}));
/**
* setTimeout, setIntervalを用いた関数の遅延実行を正常に追う
*/
it('spec13', inject(function($controller, indexService) {
// setTimeOut()などで時間を操作したい場合
// 監視関数を作成
var spy = jasmine.createSpy();
// setTimeoutによりspyは500ms後に呼ばれる。
setTimeout(function() {
spy();
}, 500);
// よってこのタイミングではspyはまだ呼ばれていない
expect(spy).not.toHaveBeenCalled();
// なのでsetTimeoutによる関数実行の遅延をキャッチしたい場合clockの仕組みを用いる
// clockをセットアップ
jasmine.clock().install();
// 新たに監視関数を作成
var spy2 = jasmine.createSpy();
// 1000ms後にspy2を実行
setTimeout(function() {
spy2();
}, 1000);
// まだ実行されていない
expect(spy2).not.toHaveBeenCalled();
// 時を加速させる(1001ms時間を進める)
jasmine.clock().tick(1001);
// ここで確認すると実行されている
expect(spy2).toHaveBeenCalled();
// 最後にclockをアンインストールして完了
jasmine.clock().uninstall();
}));
/**
* $timeoutサービスを用いた関数の遅延実行を正常に追う
*/
it('spec14', inject(function($controller, indexService, $timeout) {
// clockシステムはあくまでもsetTimeout()、及びsetInterval()へ直に働きかけるため、
// angularの$timeoutサービスを通すと正常に動作しないので注意
// $timeoutを用いたい場合下記のようにする
// 監視関数を作成
var spy = jasmine.createSpy();
// $timeoutによりspyは500ms後に呼ばれる。
$timeout(function() {
spy();
}, 500);
// よってこのタイミングではspyはまだ呼ばれていない
expect(spy).not.toHaveBeenCalled();
// この行によて$timeoutは強制的に待機時間を消費させられる
$timeout.flush();
// ここで確認すると実行されている
expect(spy).toHaveBeenCalled();
}));
/**
* afterEachブロックは各テストの後に毎回実行されている。
* 引数に`done`を受け取るようにすることで、`done`が実行されるまで次の処理に移らないようになってくれる。
* Jasmineは引数を受け取るようにすると、処理を待機するようになる。
* よって、引数を渡したにも関わらずいつまでも`done`を実行しないとタイムアウトエラーになるので注意。
* この設定の場合、各テスト処理の後1000ms待機し処理を実行しているので、各テスト間に1000msの待機時間が発生している感じになる。
*/
afterEach(function(done) {
setTimeout(function() {
console.log('afterEach');
done();
}, 1000);
});
});