Reset call on Jasmine spy does not return

Jorn picture Jorn · Jul 21, 2015 · Viewed 21.3k times · Source

I'm using a Jasmine (2.2.0) spy to see if a certain callback is called.

Test code:

it('tests', function(done) {
  var spy = jasmine.createSpy('mySpy');
  objectUnderTest.someFunction(spy).then(function() {
    expect(spy).toHaveBeenCalled();
    done();
  });
});

This works as expected. But now, I'm adding a second level:

it('tests deeper', function(done) {
  var spy = jasmine.createSpy('mySpy');
  objectUnderTest.someFunction(spy).then(function() {
    expect(spy).toHaveBeenCalled();
    spy.reset();
    return objectUnderTest.someFunction(spy);
  }).then(function() {
    expect(spy.toHaveBeenCalled());
    expect(spy.callCount).toBe(1);
    done();
  });
});

This test never returns, because apparently the done callback is never called. If I remove the line spy.reset(), the test does finish, but obviously fails on the last expectation. However, the callCount field seems to be undefined, rather than 2.

Answer

Eitan Peer picture Eitan Peer · Jul 23, 2015

The syntax for Jasmine 2 is different than 1.3 with respect to spy functions. See Jasmine docs here.

Specifically you reset a spy with spy.calls.reset();

This is how the test should look like:

// Source
var objectUnderTest = {
    someFunction: function (cb) {
        var promise = new Promise(function (resolve, reject) {
            if (true) {
                cb();
                resolve();
            } else {
                reject(new Error("something bad happened"));
            }
        });
        return promise;
    }
}

// Test
describe('foo', function () {
    it('tests', function (done) {
        var spy = jasmine.createSpy('mySpy');
        objectUnderTest.someFunction(spy).then(function () {
            expect(spy).toHaveBeenCalled();
            done();
        });
    });
    it('tests deeper', function (done) {
        var spy = jasmine.createSpy('mySpy');
        objectUnderTest.someFunction(spy).then(function () {
            expect(spy).toHaveBeenCalled();
            spy.calls.reset();
            return objectUnderTest.someFunction(spy);
        }).then(function () {
            expect(spy).toHaveBeenCalled();
            expect(spy.calls.count()).toBe(1);
            done();
        });
    });
});

See fiddle here