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

tro*_*tro 14 javascript jasmine

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

spyOn(obj, 'spy1');
spyOn(obj, 'spy2');
Run Code Online (Sandbox Code Playgroud)

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

expect(obj.spy1).toHaveBeenCalled();
expect(obj.spy2).toHaveBeenCalled();
Run Code Online (Sandbox Code Playgroud)

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

car*_*iam 8

看起来像Jasmine的人看过这篇文章或其他类似的帖子,因为这个功能存在.我不知道它已经存在了多长时间 - 他们所有的API文档都回到2.6提到它,尽管他们的存档旧版文档都没有提到它.

toHaveBeenCalledBefore(expected)
期望在另一个间谍之前调用实际值(一个间谍).

参数:

Name        Type    Description
expected    Spy     Spy that should have been called after the actual Spy.
Run Code Online (Sandbox Code Playgroud)

你的例子失败了Expected spy spy1 to have been called before spy spy2.


ale*_*ird 5

另一种选择是保留调用列表:

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'); });
});
Run Code Online (Sandbox Code Playgroud)

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

直接对比调用列表:

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

  expect(objCallOrder).toEqual(['spy1', 'spy2']);
});
Run Code Online (Sandbox Code Playgroud)

检查一些调用的相对顺序:

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'));
});
Run Code Online (Sandbox Code Playgroud)