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.