Search code examples
angularjsunit-testingangular-mock

angular unit test $httpBackend got Unexpected request


Here is my code:

export class httpService {

constructor($q, $http){
    this.$q = $q;
    this.$http = $http;
}

static getError(response) {
    if (response.data && response.data.messages) {
        return response.data.messages;
    } else {
        return ["Sorry, there is an internal issue..."];
    }
}

httpRequest(url, method, data) {
    url = encodeURI(url);
    var deferred = this.$q.defer();
    this.$http({
        method: method,
        url: url,
        data: data
    }).then(function (response) {
        deferred.resolve(response.data);
    }, function (response) {
        deferred.reject(httpService.getError(response));
    });
    return deferred.promise;
}

}

My test code:

import angular from 'angular';
import ngMock from 'angular-mocks';
import {httpService as HttpService} from '../http.service';

describe("httpService", ()=>{
    var httpService;
    var $q;
    var $timeout;
    var $httpBackend;
    var campaignHttpRequestHandler;
    var campaignTestUrl = 'api/campaign/aGJhZ2ZmZ2RmcmZ0';
    var campaignData = {
        "articles": [
            {
                "id": "1207",
                "type": "a",
                "order": 1
            },
            {
                "id": "940",
                "type": "p",
                "order": 2
            },
            {
                "id": "1268",
                "type": "a",
                "order": 3
            },
            {
                "id": "954",
                "type": "p",
                "order": 4
            }
        ],
        "year_month": "201606",
    };

    beforeEach(inject((_$q_, _$timeout_, _$httpBackend_)=>{
        $q = _$q_;
        $timeout = _$timeout_;
        $httpBackend = _$httpBackend_;
        campaignHttpRequestHandler = $httpBackend.when('Get', campaignTestUrl).respond(campaignData);

    }));

    beforeEach(()=>{
        httpService = new HttpService($q, $httpBackend);
    });

    afterEach(function () {
        $httpBackend.verifyNoOutstandingExpectation();
        $httpBackend.verifyNoOutstandingRequest();
    });

    describe("#httpRequest()", ()=>{

        it('should get campaign data', ()=>{
            $httpBackend.expect('Get', campaignTestUrl);

            httpService.httpRequest(campaignTestUrl, 'Get').then(
                (response)=>{
                    expect(response).toEqual(campaignData);
                }
            );

            $httpBackend.flush();


        });


    });





});

The Error:

#httpRequest()
      ✖ should get campaign data
        Chrome 51.0.2704 (Mac OS X 10.11.5)
      Error: Unexpected request: [object Object] undefined

And I debuged into the source code, $http has been replaced with $httpBackend. Somehow, the first parameter of $httpBackend: method, it is an object contains method, url, data, the same request parameter as in $http. Apparently, it is wrong. But I don't know how to fix it~

Help please. I have been stuck here for whole day~


Solution

  • you should pass $http instead of $httpBackend as the constructor parameter.

    Create a variable of type $http inside your test code and pass it like this

    beforeEach(()=>{
         httpService = new HttpService($q, $http)
    });
    

    It will surely work.