600 Stimmen

Kann Mockito Argumente einer mehrfach aufgerufenen Methode erfassen?

Ich habe eine Methode, die zweimal aufgerufen wird, und ich möchte das Argument des zweiten Methodenaufrufs erfassen.

Ich habe Folgendes ausprobiert:

ArgumentCaptor<Foo> firstFooCaptor = ArgumentCaptor.forClass(Foo.class);
ArgumentCaptor<Foo> secondFooCaptor = ArgumentCaptor.forClass(Foo.class);
verify(mockBar).doSomething(firstFooCaptor.capture());
verify(mockBar).doSomething(secondFooCaptor.capture());
// then do some assertions on secondFooCaptor.getValue()

Aber ich bekomme eine TooManyActualInvocations Ausnahme, da Mockito der Meinung ist, dass doSomething sollte nur einmal aufgerufen werden.

Wie kann ich das Argument des zweiten Aufrufs von doSomething ?

1032voto

proactif Punkte 10531

Ich denke, es sollte sein

verify(mockBar, times(2)).doSomething(...)

Probe aus mockito javadoc :

ArgumentCaptor<Person> peopleCaptor = ArgumentCaptor.forClass(Person.class);
verify(mock, times(2)).doSomething(peopleCaptor.capture());

List<Person> capturedPeople = peopleCaptor.getAllValues();
assertEquals("John", capturedPeople.get(0).getName());
assertEquals("Jane", capturedPeople.get(1).getName());

81voto

Maciej Dobrowolski Punkte 10788

Seit Mockito 2.0 gibt es auch die Möglichkeit, die statische Methode Matchers.argThat(ArgumentMatcher) . Mit Hilfe von Java 8 ist es jetzt viel sauberer und lesbarer zu schreiben:

verify(mockBar).doSth(argThat((arg) -> arg.getSurname().equals("OneSurname")));
verify(mockBar).doSth(argThat((arg) -> arg.getSurname().equals("AnotherSurname")));

Wenn Sie an eine niedrigere Java-Version gebunden sind, ist das auch nicht so schlimm:

verify(mockBar).doSth(argThat(new ArgumentMatcher<Employee>() {
        @Override
        public boolean matches(Object emp) {
            return ((Employee) emp).getSurname().equals("SomeSurname");
        }
    }));

Natürlich kann keiner von ihnen die Reihenfolge der Aufrufe überprüfen - dafür sollten Sie die InOrder :

InOrder inOrder = inOrder(mockBar);

inOrder.verify(mockBar).doSth(argThat((arg) -> arg.getSurname().equals("FirstSurname")));
inOrder.verify(mockBar).doSth(argThat((arg) -> arg.getSurname().equals("SecondSurname")));

Schauen Sie sich bitte an mockito-java8 Projekt, das es ermöglicht, Anrufe zu tätigen wie:

verify(mockBar).doSth(assertArg(arg -> assertThat(arg.getSurname()).isEqualTo("Surname")));

32voto

lreeder Punkte 11372

Wenn Sie nicht alle Aufrufe von doSomething() nur die letzte, können Sie einfach mit ArgumentCaptor.getValue() . Nach der Mockito javadoc :

Wenn die Methode mehrmals aufgerufen wurde, wird der zuletzt erfasste Wert zurückgegeben

Dies würde also funktionieren (vorausgesetzt Foo hat eine Methode getName() ) :

ArgumentCaptor<Foo> fooCaptor = ArgumentCaptor.forClass(Foo.class);
verify(mockBar, times(2)).doSomething(fooCaptor.capture());
//getValue() contains value set in second call to doSomething()
assertEquals("2nd one", fooCaptor.getValue().getName());

27voto

Michał Stochmal Punkte 4239

Sie können auch mit @Captor annotierte ArgumentCaptor verwenden. Zum Beispiel:

@Mock
List<String> mockedList;

@Captor
ArgumentCaptor<String> argCaptor;

@BeforeTest
public void init() {
    //Initialize objects annotated with @Mock, @Captor and @Spy.
    MockitoAnnotations.initMocks(this);
}

@Test
public void shouldCallAddMethodTwice() {
    mockedList.add("one");
    mockedList.add("two");
    Mockito.verify(mockedList, times(2)).add(argCaptor.capture());

    assertEquals("one", argCaptor.getAllValues().get(0));
    assertEquals("two", argCaptor.getAllValues().get(1));
}

8voto

Anton Seredkin Punkte 69

Mit den Lambdas von Java 8 ist eine bequeme Möglichkeit die Verwendung von

org.mockito.invocation.InvocationOnMock

when(client.deleteByQuery(anyString(), anyString())).then(invocationOnMock -> {
    assertEquals("myCollection", invocationOnMock.getArgument(0));
    assertThat(invocationOnMock.getArgument(1), Matchers.startsWith("id:"));
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X