Reputation: 7717
I'm trying to figure out how to test a service promise using karma + jasmine but without success. So far this is what I did with the result errors:
PhantomJS 2.1.1 (Mac OS X 0.0.0) The FetchData service should fetch data FAILED
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
fetchData service:
module.exports = function($http) {
return {
getFoo: function(id) {
return $http.get('https://api/' + id)
.then(function(result) {
return result.data;
});
}
}
};
test:
describe('The FetchData service', function() {
var dataFetcher;
beforeEach(angular.mock.module("myApp"))
beforeEach(inject(function(_dataFetcher_) {
dataFetcher = _dataFetcher_;
}));
it('should fetch data', function(done) {
var testData = function(res) {
expect(res.success).toBe(true);
};
var failTest = function(error) {
expect(error).toBeUndefined();
};
dataFetcher.getFoo(id)
.then(testData)
.catch(failTest);
});
});
I wonder if there's something that I might be missing that can help me understand this,
Thanks!
Upvotes: 3
Views: 107
Reputation: 7717
This is the solution I got this far, based on the actual Angularjs docs.
I hope it's self-explanatory (update based in @mehndra's answer and tips):
describe('The FetchData service', function() {
var dataFetcher, $httpBackend;
beforeEach(angular.mock.module("myApp"));
beforeEach(inject(function(_dataFetcher_, _$httpBackend_) {
dataFetcher = _dataFetcher_;
$httpBackend = _$httpBackend_;
}));
afterEach(function() {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
it('should fetch data', function () {
var status, data,
pid = 2140,
api = 'https://api';
function successHandler(res){
status = 'success';
data = res.data;
expect(res.success).toEqual(true);
expect(status).toEqual('success');
}
function errorHandler(){
status = 'error'
}
$httpBackend
.when('GET', api + '/' + pid)
.respond({ success: true });
$httpBackend
.when('GET', api + '/' + pid)
.respond(500, 'An error has occured.');
dataFetcher.get(pid).then(successHandler, errorHandler);
$httpBackend.flush();
});
});
Upvotes: 0
Reputation: 308
You need to inject the $httpBackend service in your tests to mock the $http service.
Then you need to call $httpBackend.flush to mock the actual HTTP call. Please check the angular docs for example.
Edit:
it('should fetch data', function () {
var status, data;
function successCB(response){
status = 'success';
data = response.data;
}
function errorCB(){
status = 'error'
}
//only pass the success and error callbacks here
dataFetcher.get(1).then(successCB, errorCB);
// you need to stop it
$httpBackend.flush();
//assert for success
$httpBackend
.when('GET', 'https://api/1')
.respond(200, {foo:'bar'});
expect(status).toEqual('success');
expect(data).toEqual({foo: 'bar'});
//assert for error
$httpBackend
.when('GET', 'https://api/1')
.respond(500, 'An error has occured.');
expect(status).toEqual('success');
});
Upvotes: 1