Есть ли способ проверить порядок выполнения шпионских программ с помощью Jasmine?

У меня есть два объекта, которые были установлены как шпионы с Jasmine:

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

Мне нужно проверить, что вызовы spy1 поступают до вызовов spy2. Я могу проверить, вызваны ли они оба из них:

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

но это пройдет, даже если obj.spy2() был вызван первым. Есть ли простой способ проверить, что один был вызван перед другим?

Ответ 1

Похоже, что люди Жасмин видели этот пост или другие, как это, потому что эта функциональность существует. Я не уверен, как долго это было - все их документы API до 2.6 упоминают об этом, хотя ни один из их архивных документов старого стиля не упоминает об этом.

toHaveBeenCalledBefore (expected)
expect фактическое значение (a 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.

Ответ 2

До сих пор я делал это следующим образом, но это кажется неудобным и не будет хорошо масштабироваться:

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

Ответ 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'));
});