3

I'm using jasmine-node to test my server. I want to fake/bypass some validation related code in my user class. So I would set up a spy like this -

var user = {
  email: 'email@email.com',
  password: 'password'
}

spyOn(User, 'validateFields').andReturn(user);

However the validateFields function is asynchronous...

User.prototype.validateFields = function(user, callback) {

  // validate the user fields

  callback(err, validatedUser);
}

So I actually would need something like this which fakes a callback instead of a return -

var user = {
  email: 'email@email.com',
  password: 'password'
}

spyOn(User, 'validateFields').andCallback(null, user);

Is anything like this possible with Jasmine?

sonicboom
  • 4,928
  • 10
  • 42
  • 60

3 Answers3

2

There are two ways for this. First you can spy and then get the args for first call of the spy and call thisfunction with your mock data:

spyOn(User, 'validateFields')
//run your code
User.validateFields.mostRecentCall.args[1](errorMock, userMock)

The other way would be to use sinonJS stubs.

sinon.stub(User, 'validateFields').callsArgWith(1, errorMock, userMock);

This will immediately call the callback function with the mocked data.

Andreas Köberle
  • 106,652
  • 57
  • 273
  • 297
0

You could pass in a callback function and ask whether this function has been called.

Christian
  • 6,961
  • 10
  • 54
  • 82
0

Sorry to respond with asynchronous 4 years delay, but I've been just wondering how to solve similar issue and figured out that I can combine jasmine done callback and and.callFake spy method. Consider the abstract sample below:

describe('The delayed callback function', function(){

  it('should be asynchronously called',function(done){
    var mock = jasmine.createSpy('mock');
    mock.and.callFake(function(){
      expect(mock).toHaveBeenCalled();
      done();
    });
    delayed(mock);
  });

});

function delayed(callback){
  setTimeout(function(){
    callback();
  },2000);
}
Paweł
  • 4,238
  • 4
  • 21
  • 40