javascriptjasminespyjasmine2.0

Reset call on Jasmine spy does not return


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.


Solution

  • 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