Karma-Jasmine: Unexpected request: GET ... No more request expected

10,731

Solution 1

Here are some pointers and a demo http://plnkr.co/edit/Kp9C4S6oNVu1MM1YLb90?p=preview

  • You should be using $httpBackend.flush() and not setTimeout(). This way you can control when your asynchronous request returns. It makes it easier to test.

  • Pull out your $httpBackend and controller into the beforeEach statement. When your controller is created it fires off both url. Then you can evaluate it individually. When it is isolated in the it statement it does not call the other $http and throws the unexpected url error.

  • You should also mock the response of your $http request and not passThrough. You are not always going to have internet connection and the response can change. So make the mock data look like what you expect.

  • In addition, $httpBackend.whenGET('httpS://MY_DOMAIN_2.org/projectList') is requesting the incorrect url. It should be a lowercase s and a .com url. This is because the controller is requesting

    $http.get('https://MY_DOMAIN_2.com/projectList')

Solution 2

Don't use timeouts, and test them at the same time:

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([]);
});
Share:
10,731
FrancescoMussi
Author by

FrancescoMussi

Full-stack developer based in Riga, Latvia. Hope Socrates is proud of my Socratic badge on StackOverflow.

Updated on June 17, 2022

Comments

  • FrancescoMussi
    FrancescoMussi almost 2 years

    THE SITUATION:

    I am testing two different http calls in my AngularJs app.

    There is a strange behavior. If i test each one separately, with the other temporary commented out (in the controller and in the test) each one works fine and the test passes.

    But if I run karma when there are both the tests, they fail, giving the following error message:

    Unexpected request: GET https://MY_DOMAIN_2.com/list_project
    No more request expected
    

    THE CONTROLLER:

    .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();
    
    })
    

    THE TEST:

    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);
    
        });
    
    });
    
    });
    

    THE QUESTION:

    Why i am getting that error message? The code should be fine since separately they are working fine. Am I missing something?

    Thank you!