初期化中にGET呼び出しを行うコントローラーの単体テストの問題を解決する方法を理解するのに苦労しています。
最初の GET 呼び出しのために、POST 要求を実行するコントローラー メソッドをテストすると、テストで次のエラーが発生します。
エラー: 予期しない要求: GET
コントローラーの主要部分は次のようになります。
.controller('someController', function($scope, $http, $log) {
$scope.posts = [];
$scope.content = '';
$scope.read = function() {
$http.get('/read.php')
.success(function(data) {
$scope.posts = data;
})
.error(function(data, status, headers, config) {
throw new Error('Something went wrong with reading data');
});
};
$scope.read();
$scope.write = function() {
$http({
method: 'POST',
url: '/write.php',
data: "content=" + $scope.content,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})
.success(function(data) {
$scope.posts.push({ id : data.id, task : $scope.content })
})
.error(function(data, status, headers, config) {
throw new Error('Something went wrong with writing data');
});
};
});
ご覧のとおり、定義の直後に read() メソッドを呼び出しているため、ページの読み込み時にすべてのレコードがデータベースから取得されます。
.config() または他のサービスで同じことを試しましたが、明らかに結果は同じです。
今-私のテストは次のとおりです:
describe('someController tests', function() {
var $scope,
$http,
$httpBackend,
$log;
beforeEach(function() {
module('myApp');
inject(function($rootScope, _$http_, _$httpBackend_, _$log_) {
$scope = $rootScope.$new();
$http = _$http_;
$httpBackend = _$httpBackend_;
$log = _$log_;
});
$httpBackend.expectGET("/mod/read.php").respond({});
});
it('should add new record', inject(function($controller) {
$controller('ToDoController', {
$scope : $scope,
$http : $http,
$log : $log
});
$scope.posts = [];
$scope.content = 'Some content';
$httpBackend
.whenPOST('/write.php')
.respond({ id : 1, content : $scope.content });
$scope.write();
$httpBackend.flush();
expect($scope.posts.length).toBe(1);
afterEach(function() {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
}));
});
さて、このコードについていくつか質問があります。
ページの読み込み時にコントローラー内でメソッドを呼び出すことは良い習慣と考えられていますか? ドキュメント内で ng-init を使用して呼び出すと、これですべての問題が解決することはわかっていますが、このアプローチは好きではありません。
私が呼び出しているテストの beforeEach() メソッドで:
$httpBackend.expectGET("/mod/read.php").respond({});
初期化中の read() メソッドの呼び出しを反映するためですが、繰り返しますが、これがここで行うべき正しいことかどうかはわかりません。削除すると、「新しいレコードを追加する必要がある」テストが上記のエラーで失敗することはわかっています。
afterEach() を it() ブロックの外に配置する必要があることはわかっていますが、これを行うと、同じ問題が発生しますが、この記述ブロック内のすべてのテストにエラーが適用されます。それを it() ブロック内に配置することは、悪い習慣/間違っていると見なされますか?
呼び出しが beforeEach() ループで既にトリガーされている場合、read() テストを実行するにはどうすればよいですか?
最後に、コントローラーとテストを改善/書き直して、それが最適に機能することを確認するための提案は何ですか?
私はTDDにかなり慣れていないので、このトピックについての私の限られた理解に過ぎないと確信していますが、建設的な助けをいただければ幸いです。