Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to verify the order of spy executions with Jasmine?

I've got two objects that have been set up as spies with Jasmine:

spyOn(obj, 'spy1');
spyOn(obj, 'spy2');

I need to verify that calls to spy1 come before calls to spy2. I can check if both of them are called:

expect(obj.spy1).toHaveBeenCalled();
expect(obj.spy2).toHaveBeenCalled();

but this will pass even if obj.spy2() was called first. Is there an easy way of verifying that one was called before the other?

like image 860
tro Avatar asked Nov 18 '13 19:11

tro


3 Answers

Looks like the Jasmine folks saw this post or others like it, because this functionality exists. I'm not sure how long it's been around -- all of their API docs back to 2.6 mention it, though none of their archived older style docs mention it.

toHaveBeenCalledBefore(expected)
expect the actual value (a Spy) to have been called before another Spy.

Parameters:

Name        Type    Description
expected    Spy     Spy that should have been called after the actual Spy.

A failure for your example looks like Expected spy spy1 to have been called before spy spy2.

like image 97
carpeliam Avatar answered Nov 15 '22 17:11

carpeliam


So far I've been doing it as follows, but it seems awkward and won't scale well:

obj.spy1.andCallFake(function() {
    expect(obj.spy2.calls.length).toBe(0);
});
like image 22
tro Avatar answered Nov 15 '22 17:11

tro


Another alternative is to keep a list of calls:

var objCallOrder;
beforeEach(function() {
  // Reset the list before each test
  objCallOrder = [];
  // Append the method name to the call list
  obj.spy1.and.callFake(function() { objCallOrder.push('spy1'); });
  obj.spy2.and.callFake(function() { objCallOrder.push('spy2'); });
});

Which lets you check the order in a few different ways:

Directly compare to the call list:

it('calls exactly spy1 then spy2', function() {
  obj.spy1();
  obj.spy2();

  expect(objCallOrder).toEqual(['spy1', 'spy2']);
});

Check the relative order of a few of the calls:

it('calls spy2 sometime after calling spy1', function() {
  obj.spy1();
  obj.spy3();
  obj.spy4(); 
  obj.spy2();

  expect(obj.spy1).toHaveBeenCalled();
  expect(obj.spy2).toHaveBeenCalled();
  expect(objCallOrder.indexOf('spy1')).toBeLessThan(objCallOrder.indexOf('spy2'));
});
like image 31
alexanderbird Avatar answered Nov 15 '22 17:11

alexanderbird