Karma-Jasmine:意外请求:GET ......不再需要请求

时间:2015-10-19 12:11:00

标签: javascript angularjs unit-testing karma-runner karma-jasmine

情况:

我正在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);

    });

});

});

问题:

为什么我收到该错误消息? 代码应该没问题,因为它们分别正常工作。我错过了什么吗?

谢谢!

2 个答案:

答案 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([]);
});