Skip to content

Mockito.only() points to the wanted call as unwanted if it is the first being called. #3286

Closed
@PiotrPrzybylak

Description

Mockito.only() Javadoc claims that it is equivalent to:

verify(mock).someMethod();
verifyNoMoreInteractions(mock)

 * <pre class="code"><code class="java">
 *   verify(mock, only()).someMethod();
 *   //above is a shorthand for following 2 lines of code:
 *   verify(mock).someMethod();
 *   verifyNoMoreInteractions(mock);
 * </code></pre>

It is really not. The most important issue is that Mockito.only() points to the wanted call as unwanted if it is the first being called. Example:

package codepractice.tddexample;

import org.junit.jupiter.api.Test;

import static org.mockito.Mockito.*;

public class MockitoOnlyExampleTest {

    @Test
    public void shouldDeleteProduct() {
        ProductDeleter productDeleter = mock(ProductDeleter.class);

        productDeleter.execute(3);
        productDeleter.execute(2);

        verify(productDeleter, only()).execute(3);
//        verify(productDeleter).execute(3);
//        verifyNoMoreInteractions(productDeleter);
    }
}

The result is:

org.mockito.exceptions.verification.NoInteractionsWanted: 
No interactions wanted here:
-> at codepractice.tddexample.MockitoOnlyExampleTest.shouldDeleteProduct(MockitoOnlyExampleTest.java:16)
But found this interaction on mock 'productDeleter':
-> at codepractice.tddexample.MockitoOnlyExampleTest.shouldDeleteProduct(MockitoOnlyExampleTest.java:13)
***
For your reference, here is the list of all invocations ([?] - means unverified).
1. [?]-> at codepractice.tddexample.MockitoOnlyExampleTest.shouldDeleteProduct(MockitoOnlyExampleTest.java:13)
2. [?]-> at codepractice.tddexample.MockitoOnlyExampleTest.shouldDeleteProduct(MockitoOnlyExampleTest.java:14)


	at codepractice.tddexample.MockitoOnlyExampleTest.shouldDeleteProduct(MockitoOnlyExampleTest.java:16)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)

And should be :

  • "But found this interaction on mock 'productDeleter'":" -points to line 14 instead of 13
  • Wanted interaction marked as verified
org.mockito.exceptions.verification.NoInteractionsWanted: 
No interactions wanted here:
-> at codepractice.tddexample.MockitoOnlyExampleTest.shouldDeleteProduct(MockitoOnlyExampleTest.java:16)
But found this interaction on mock 'productDeleter':
-> at codepractice.tddexample.MockitoOnlyExampleTest.shouldDeleteProduct(MockitoOnlyExampleTest.java:14)
***
For your reference, here is the list of all invocations ([?] - means unverified).
1. -> at codepractice.tddexample.MockitoOnlyExampleTest.shouldDeleteProduct(MockitoOnlyExampleTest.java:13)
2. [?]-> at codepractice.tddexample.MockitoOnlyExampleTest.shouldDeleteProduct(MockitoOnlyExampleTest.java:14)


	at codepractice.tddexample.MockitoOnlyExampleTest.shouldDeleteProduct(MockitoOnlyExampleTest.java:16)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)

I will make PR soon. I made this issue to have an issue number for commit message.

Versions:
Mockito: 5.11.0
jdk: OpenJdk-21
os: Windows 10

  • The mockito message in the stacktrace have useful information, but it didn't help
  • [x ] The problematic code (if that's possible) is copied here;
    Note that some configuration are impossible to mock via Mockito
  • Provide versions (mockito / jdk / os / any other relevant information)
  • Provide a Short, Self Contained, Correct (Compilable), Example of the issue
    (same as any question on stackoverflow.com)
  • Read the contributing guide

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions