Mockito перевіряють порядок / послідовність викликів методу


205

Чи є спосіб перевірити, чи methodOneвикликається раніше methodTwoв Mockito?

public class ServiceClassA {
    public void methodOne(){}
 }

public class ServiceClassB {
    public void methodTwo(){}
 }

public class TestClass {
    public void method(){
        ServiceClassA serviceA = new ServiceClassA();
        ServiceClassB serviceB = new ServiceClassB();
        serviceA.methodOne();
        serviceB.methodTwo();
    }
}

Відповіді:


305

InOrder допомагає вам це зробити.

ServiceClassA firstMock = mock(ServiceClassA.class);
ServiceClassB secondMock = mock(ServiceClassB.class);

Mockito.doNothing().when(firstMock).methodOne();   
Mockito.doNothing().when(secondMock).methodTwo();  

//create inOrder object passing any mocks that need to be verified in order
InOrder inOrder = inOrder(firstMock, secondMock);

//following will make sure that firstMock was called before secondMock
inOrder.verify(firstMock).methodOne();
inOrder.verify(secondMock).methodTwo();

5
Це правильно, хоча заклики до виконання нічого тут не потрібні, окрім як заповнювача для інших заглушок. Mockito за замовчуванням беззвучно прийме виклики недійсних методів.
Джефф Боуман

1
Він приймає їх, поки у об'єкта немає залежностей, якщо у об'єкта залежність, буде виняток =)
Koitoer

14
розглянемо inOrder.verifyNoMoreInteractions();після останньої перевірки в цьому прикладі, щоб перевірити, чи не було здійснено інших дзвінків.
DwB

1
Просто для уточнення: Безпечно визначити inOrder безпосередньо перед перевіркою - після виклику деяких (перевірених) методів на макети.
user3078523

Чи однакові результати для inOrder(firstMock, secondMock)і inOrder(secondMock, firstMock)? Можливо, ви можете оновити відповідь, щоб зробити про це помітку.
kevinarpe

95

Зауважте, що ви також можете використовувати клас InOrder для перевірки того, що різні методи викликаються в порядку на одному макеті, а не лише на двох або більше макетах.

Припустимо, у мене є два класи Fooта Bar:

public class Foo {
  public void first() {}
  public void second() {}
}

public class Bar {
  public void firstThenSecond(Foo foo) {
    foo.first();
    foo.second();
  }
}

То я можу додати тестовий клас тест , який Bar«S firstThenSecond()метод фактично викликає first(), то second()і не second(), тоді first(). Дивіться наступний тестовий код:

public class BarTest {
  @Test
  public void testFirstThenSecond() {
    Bar bar = new Bar();
    Foo mockFoo = Mockito.mock(Foo.class);
    bar.firstThenSecond(mockFoo);

    InOrder orderVerifier = Mockito.inOrder(mockFoo);
    // These lines will PASS
    orderVerifier.verify(mockFoo).first();
    orderVerifier.verify(mockFoo).second();

    // These lines will FAIL
    // orderVerifier.verify(mockFoo).second();
    // orderVerifier.verify(mockFoo).first();
  }
}

1
Це повинен був бути коментарем до прийнятої відповіді, а не зовсім новою відповіддю.
ач

12
Я не згоден з вашим коментарем @ach Зразок коду допомагає, тому нова відповідь має сенс.
Snekse

2
Чи є спосіб перевірити один і той же метод двічі, але перевірити порядок переданих параметрів? наприклад Спочатку find('foo'), потімfind('bar')
Snekse

1
Схоже , що це може бути моя відповідь stackoverflow.com/questions/36573399 / ...
Snekse

3
Це насправді кращий приклад, ніж прийнята відповідь, оскільки вона показує більш типове використання, ніжdoNothing()
Архімед

37

Так, це описано в документації. Ви повинні використовувати клас InOrder .

Приклад (якщо припустити два макети):

InOrder inOrder = inOrder(serviceAMock, serviceBMock);

inOrder.verify(serviceAMock).methodOne();
inOrder.verify(serviceBMock).methodTwo();

1

З BDD - це

@Test
public void testOrderWithBDD() {


    // Given
    ServiceClassA firstMock = mock(ServiceClassA.class);
    ServiceClassB secondMock = mock(ServiceClassB.class);

    //create inOrder object passing any mocks that need to be verified in order
    InOrder inOrder = inOrder(firstMock, secondMock);

    willDoNothing().given(firstMock).methodOne();
    willDoNothing().given(secondMock).methodTwo();

    // When
    firstMock.methodOne();
    secondMock.methodTwo();

    // Then
    then(firstMock).should(inOrder).methodOne();
    then(secondMock).should(inOrder).methodTwo();


}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.