有没有办法用Jasmine来验证间谍执行的顺序?

时间:2013-11-18 19:07:36

标签: javascript jasmine

我有两个与Jasmine建立间谍的对象:

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

我需要在调用spy1之前验证对spy2的来电。我可以检查它们是否都被调用:

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

但即使首先调用obj.spy2(),这也会通过。有没有一种简单的方法来验证一个人在另一个之前被调用了?

3 个答案:

答案 0 :(得分:7)

看起来像Jasmine的人看过这篇文章或其他人喜欢它,因为this functionality exists。我不知道它已经存在了多长时间 - 他们所有的API文档都回到2.6提到它,尽管他们的档案旧版文档都没有提到它。

  

toHaveBeenCalledBefore(expected
  expect在另一个Spy之前调用的实际值(Spy)。

     

<强>参数:

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

您示例的失败看起来像Expected spy spy1 to have been called before spy spy2

答案 1 :(得分:4)

到目前为止,我一直这样做,但看起来很尴尬,不会很好地扩展:

obj.spy1.andCallFake(function() {
    expect(obj.spy2.calls.length).toBe(0);
});

答案 2 :(得分:3)

另一种方法是保留一个电话列表:

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'); });
});

这使您可以通过几种不同的方式检查订单:

直接与通话清单进行比较:

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

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

检查一些来电的相对顺序:

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'));
});