Testing methods returning promise using jasmine

447 views Asked by At

I am using jasmine & karma to test my angular app. I have a service as follows

app.service('demo1', function( $http ){
    this.send = function(){
        return $http({
            url: 'someurl'        
        });
    }
});

The response is mocked using ngMockE2E.

My jasmine spec is as follows:

describe('Testing asynchronus', function(){
    var demoService;
    beforeEach(function(){
        module('app');
        inject(function( demo1 ){
            demoService = demo1
        });
    });

    it('Should be able to test promise', function(){            
        demoService.send().then(function( data ){
            expect(data.status).toBe(true);
        });
    });    
});

Now the problem is, the expect is not executing. the test being passed every time, no matter what the value of data.status is. I need help on how to test these kinds of scenarios? Thanks in advance.

Real code:

describe("Testing MetaService", function(){

    var _entityMeta_, metaService, scope;

    beforeEach(function(){
        console.log( '---------------------- Starting Meta Service fetchEntityMeta Test ---------------------------' );
        module(APP_MODULE_NAME);

        inject(function(_entityMeta_, _metaService_, $rootScope){
            metaService = _metaService_;
            entityMeta = _entityMeta_;
            scope = $rootScope.$new();
        });
    });

    afterEach(function(){
        console.log( '---------------------- Ending Meta Service fetchEntityMeta Test ---------------------------' );
    });


    // Giving mock data from entityMeta.person as input
    it("Should have a valid structure", function($rootScope){ 

        console.log( '////////////////////////////////////////////' );
        metaService.fetchEntityMeta('person').then(function( data ){
            console.log( data );
            expect(data.type).toBe('object');
            expect(data.properties.length).toBeGreaterThan(0);
            expect(data.definitions.length).toBeGreaterThan(0);            
        });        

    });

});

I am getting following error:

Error: Timeout - Async callback was not invoked within timeout specified
 by jasmine.DEFAULT_TIMEOUT_INTERVAL.
2

There are 2 answers

4
z0r0 On

try to add

beforeEach(module('app'));

under the describe

2
phtrivier On

If you're using Jasmine 2, the argument to the callback passed to it is supposed to be a done function called when the test finished. (The test runner will time out if it is never called.)

(See the official doc here, or one of many blog posts.)

I don't really understand why you pass $rootScope in this case, but the error message looks like a complain because the done function (which happens to be named $rootScope here) has not be called.

This might work :

// Giving mock data from entityMeta.person as input
it("Should have a valid structure", function(done){ 

    console.log( '////////////////////////////////////////////' );
    metaService.fetchEntityMeta('person').then(function( data ){
        console.log( data );
        expect(data.type).toBe('object');
        expect(data.properties.length).toBeGreaterThan(0);
        expect(data.definitions.length).toBeGreaterThan(0);            
        done();
    }, function (e) {
        // The promise was not resolved, this is most likely an
        // implementation error. Let's fail the test !
        throw new Error(e);
    });        

});

If the then part is never called, the done function will not either, an you'll get the timeout error you're seeing right now.