情况:
我正在AngularJs应用中测试两个不同的http调用。
有一种奇怪的行为。如果我单独测试每一个,另一个临时注释(在控制器和测试中)每个工作正常,测试通过。
但如果我在两次测试时都运行业力,那么他们就会失败,并给出以下错误信息:
Unexpected request: GET https://MY_DOMAIN_2.com/list_project
No more request expected
控制器:
.controller('TestController', function($scope, $http, $timeout) {
$scope.getLanguageList = function()
{
$http.get('http://MY_DOMAIN_1.org/languageList').then(function(resp)
{
$scope.language_list = resp.data;
},
function(err)
{
$scope.language_list = [];
})
}
$scope.language_list = [];
$scope.getLanguageList();
$scope.get_project_list = function()
{
$http.get('https://MY_DOMAIN_2.com/projectList').then(function(resp)
{
$scope.project_list = resp.data;
},
function(err)
{
$scope.project_list = [];
})
}
$scope.project_list = [];
$scope.get_project_list();
})
测试:
describe('Http requests tests', function() {
beforeEach(module('my_app.controllers'));
var $controller;
var $httpBackend;
var $scope;
var $timeout;
describe('Lists test', function()
{
beforeEach(angular.mock.http.init);
afterEach(angular.mock.http.reset);
beforeEach(inject(function(_$controller_, _$httpBackend_)
{
$controller = _$controller_;
$scope = {};
$httpBackend = _$httpBackend_;
}));
it('should load default language list', function (done)
{
$httpBackend.whenGET('http://MY_DOMAIN_1.org/languageList').passThrough();
var TestController = $controller('TestController', { $scope: $scope });
setTimeout(function()
{
expect($scope.language_list).not.toEqual([]);
done();
}, 1000);
});
it('should load default project list', function (done)
{
$httpBackend.whenGET('https://MY_DOMAIN_2.org/projectList').passThrough();
var TestController = $controller('TestController', { $scope: $scope });
setTimeout(function()
{
expect($scope.project_list).not.toEqual([]);
done();
}, 1000);
});
});
});
问题:
为什么我收到该错误消息? 代码应该没问题,因为它们分别正常工作。我错过了什么吗?
谢谢!
答案 0 :(得分:5)
以下是一些指示和演示http://plnkr.co/edit/Kp9C4S6oNVu1MM1YLb90?p=preview
您应该使用$httpBackend.flush()
而不是setTimeout()
。这样您就可以控制异步请求何时返回。它使测试更容易。
将$ httpBackend和controller拉出到beforeEach语句中。创建控制器后,它会触发两个url。然后你可以单独评估它。当它在it
语句中被隔离时,它不会调用其他$ http并抛出意外的url错误。
您还应该模拟$ http请求的响应,而不是passThrough。您并不总是会有互联网连接,响应可能会发生变化。因此,使模拟数据看起来像您期望的那样。
此外,$httpBackend.whenGET('httpS://MY_DOMAIN_2.org/projectList')
正在请求错误的网址。它应该是小写的s
和.com
网址。这是因为控制器正在请求
$ http.get( 'https://MY_DOMAIN_2.com/projectList')
答案 1 :(得分:3)
不要使用超时,并同时测试它们:
it('should load default language list and the default project list', function (){
$httpBackend.whenGET('http://MY_DOMAIN_1.org/languageList').passThrough();
$httpBackend.whenGET('httpS://MY_DOMAIN_2.org/projectList').passThrough();
var TestController = $controller('TestController', { $scope: $scope });
$httpBackend.flush();
expect($scope.language_list).not.toEqual([]);
expect($scope.project_list).not.toEqual([]);
});