Mockito: Как вы проверяете групповой порядок определенных групп вызовов методов?
Я использую Mockito для проверки заказов вызовов методов с объектом InOrder
. Но меня не интересует полное упорядочение вызовов, только то, что определенная группа вызовов метода все происходит до вызова других методов. Например, например
@Test
public void testGroupOrder() {
Foo foo1 = mock(Foo.class);
Foo foo2 = mock(Foo.class);
Bar underTest = new Bar();
underTest.addFoo(foo1);
underTest.addFoo(foo2);
underTest.fire()
InOrder inOrder = inOrder(foo1,foo2);
inorder.verify(foo1).doThisFirst();
inorder.verify(foo2).doThisFirst();
inorder.verify(foo1).beforeDoingThis();
inorder.verify(foo2).beforeDoingThis();
}
Но этот тест слишком много проверяет, так как он проверяет порядок экземпляров Foo
. Но меня интересует только порядок разных методов. На самом деле я хочу, чтобы underTest
не различал экземпляры Foo
, у них может быть внутренний порядок или нет, поэтому не имеет значения, в каком порядке вызывается foos. Я хотел бы сохранить это как деталь реализации.
Но важно, чтобы doThisFirst()
был вызван во всех foos до того, как beforeDoingThis()
вызывается на любом другом foo. Можно ли выразить это с помощью Мокито? Как?
Ответы
Ответ 1
Mockito проверяет порядок по всем mocks, которые были переданы в функцию inorder. Поэтому, если вы не хотите проверять порядок foos, вам нужно создать два отдельных in-orders. то есть.
@Test
public void testGroupOrder() {
Foo foo1 = mock(Foo.class);
Foo foo2 = mock(Foo.class);
Bar underTest = new Bar();
underTest.addFoo(foo1);
underTest.addFoo(foo2);
underTest.fire()
InOrder inOrderFoo1 = inOrder(foo1);
inOrderFoo1.verify(foo1).doThisFirst();
inOrderFoo1.verify(foo1).beforeDoingThis();
InOrder inOrderFoo2 = inOrder(foo2);
inOrderFoo2.verify(foo2).doThisFirst();
inOrderFoo2.verify(foo2).beforeDoingThis();
}
Ответ 2
Вы можете получить доступ к внутренним компонентам, выполнив свой собственный режим проверки (благодаря этому ответу для обучения меня, мой код основан на нем). Реализация не завершена, но вы получите эту идею.
К сожалению, Mockito не документирует этот интерфейс, они, вероятно, считают его внутренним (поэтому он не может быть на 100% стабильным в будущих выпусках).
verify(foo1, new DoFirst()).doThisFirst();
verify(foo2, new DoFirst()).doThisFirst();
verify(foo1, new DoSecond()).beforeDoingThis();
verify(foo1, new DoSecond()).beforeDoingThis();
а затем
// Set to true when one
boolean secondHasHappened = false;
// Inner classes so they can reach the boolean above.
// Gives an error of any DoSecond verification has happened already.
public class DoFirst implements VerificationMode {
public void verify(VerificationData data) {
List<Invocation> invocations = data.getAllInvocations()
InvocationMatcher matcher = data.getWanted();
Invocation invocation = invocations.get(invocations.size() - 1);
if (wanted.matches(invocation) && secondHasHappened) throw new MockitoException("...");
}
}
// Registers no more DoFirst are allowed to match.
public class DoSecond implements VerificationMode {
public void verify(VerificationData data) {
List<Invocation> invocations = data.getAllInvocations()
InvocationMatcher matcher = data.getWanted();
Invocation invocation = invocations.get(invocations.size() - 1);
if (!wanted.matches(invocation)) secondHasHappened = true;
}
}