westandy westandy - 6 months ago 69
AngularJS Question

$httpBackend expectGET not returning expected data

I will just start out saying that $httpBackend and spyOn are pretty new to me, and I am struggling to get a clear picture of what is happening. Basically, I'm trying to do an $httpBackend.expectGET('/myroute/').respond(...) and then use spyOn, but I keep getting

Expected [ ] to equal Object({ success: true, message: 'Yeah!' })


Here's the code I'm trying to test:

angular.module('TestModule')
.service('TestService',TestService);

TestService.$inject = ['$http'];
function TestService($http){
var service = {};
service.DoIt = DoIt;
return service;

function DoIt() {
return $http.get('/myroute/')
.then(handleSuccess,handleError('Error happened!'));
}

function handleSuccess(res) {
return res.data;
}

function handleError(error) {
return function(){
return {success: false, message: error}
};
}
}


Here's my Karma-Jasmine test:

describe('Test Module',function(){
beforeEach(module('TestModule'));

describe('TestService Tests',function(){
var service,$httpBackend;
beforeEach(inject([
'$injector',
function($injector){
$httpBackend = $injector.get('$httpBackend');
service = $injector.get('TestService');
}
]));

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

it('should DoIt',function(){
var mockResponse = {
data : {success:true, message:"Yeah!"}
};

$httpBackend.expectGET('/myroute')
.respond(Promise.resolve(mockResponse));

spyOn(service,'DoIt').and.callThrough();

service.DoIt().then(function(data){
expect(service.DoIt).toHaveBeenCalled();
expect(data).toEqual(mockResponse.data); <-- ERROR OCCURS HERE -->
});

$httpBackend.flush();
});

});
});


Further information:

Using the example I found here: http://www.bradoncode.com/blog/2015/06/26/unit-testing-http-ngmock-fundamentals/, I tried this in my test code:

it('should DoIt',inject(function($http){
var promise = $http.get('/myroute').then(handleSuccess,handleError('bad stuff happened'));
promise.then(function(data){
console.log('Data: ' + JSON.stringify(data,null,3));
});

$httpBackend.expect('GET','/myroute').respond(200,{data:'Yeah!'});
$httpBackend.flush();
}));

function handleSuccess(response) {return response.data;}
function handleError(error){
return function(){
return {success:false,message:error};
};
}


This gives me the response that I expect: 'Data: {"data": "yeah"}'

My updated question: I thought service.DoIt() was doing the same thing as the promise. What is going on here? Am I not injecting my service? I do not understand how Karma expects me to stage this test. Any help, please!

Answer

If I understand your intention with the test correctly, I believe this is what you need:

describe('Test Module', function() {

    var $httpBackend, service;

    beforeEach(module('TestService'));

    beforeEach(inject(function(_$httpBackend_, _TestService_) {
        $httpBackend = _$httpBackend_;
        service = _TestService_;
    }));

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

    it('should DoIt', function() {
        var mockResponse = {
            data: { success: true, message: "Yeah!" }
        };

        $httpBackend.expectGET('/myroute/')
            .respond(mockResponse);

        service.DoIt().then(function(data) {
            expect(data).toEqual(mockResponse);
        });

        $httpBackend.flush();
    });

});
Comments