我很难理解如何解决单元测试控制器的问题,该控制器在初始化期间会进行 GET 调用。
在测试执行 POST 请求的控制器方法时,由于初始 GET 调用,我在测试中收到以下错误:
错误:意外请求: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() 块之外,但是如果我这样做 - 它会导致同样的问题,但是错误将适用于这个 describe 块中的所有测试。将它放在 it() 块内是否被认为是一种不好的做法/不正确?
如果在 beforeEach() 循环中已经触发了调用,我将如何执行 read() 测试?
最后 - 你有什么建议来改进/重写控制器和测试以确保它发挥最佳效果?
我对 TDD 很陌生——所以我确信这只是我对这个主题的有限理解,但希望能得到一些建设性的帮助。