ntolch
ntolch

Reputation: 13

How can I solve this Mockito MissingMethodInvocationException using when()...?

In Eclipse, using junit and Mockito. I'm trying to test that a method returns a List of certain size, but get the following error:

org.mockito.exceptions.misusing.MissingMethodInvocationException: when() requires an argument which has to be 'a method call on a mock'. For example: when(mock.getArticles()).thenReturn(articles);

Also, this error might show up because: 1. you stub either of: final/private/equals()/hashCode() methods. Those methods cannot be stubbed/verified. 2. inside when() you don't call method on mock but on some other object.

My test:

class ValidateBookResultsTests {

public static ArrayList<Book> searchResults = new ArrayList<Book>();
public static List<Book> topFive;
public static ArrayList<String> authors = new ArrayList<String>();

public static Book book1;
public static Book book2;
public static Book book3;
public static Book book4;
public static Book book5;
public static Book book6;

@BeforeEach
public void setUp() {
    book1 = new Book("title1", authors, "publisher1");
    book2 = new Book("title2", authors, "publisher2");
    book3 = new Book("title3", authors, "publisher3");
    book4 = new Book("title4", authors, "publisher4");
    book5 = new Book("title5", authors, "publisher5");
    book6 = new Book("title6", authors, "publisher6");

    searchResults.add(book1);
    searchResults.add(book2);
    searchResults.add(book3);
    searchResults.add(book4);
    searchResults.add(book5);
    searchResults.add(book6);
}

@Test
public void returnFiveBooksFromSearchResults() {
    authors.add("John Doe");
    authors.add("Bill Gates");

    BookSearch mockBookSearch = Mockito.mock(BookSearch.class);
    Mockito.when(mockBookSearch.returnFiveBooks(searchResults)).thenReturn(topFive);

    System.out.println("return books: " + mockBookSearch.returnFiveBooks(searchResults));
    System.out.println("top: "+ topFive);

    assertEquals(topFive.size(), 5);
 }
}

My relevant code:

public static List<Book> returnFiveBooks(ArrayList<Book> searchResults) {
  Collections.shuffle(searchResults);
  topFive = searchResults.subList(0, 5);

  printFiveResults();

  return topFive; }

I've read other solutions that say to create a mock class/object, which I believe I've done with "BookSearch mockBookSearch = Mockito.mock(BookSearch.class);"

What am I missing?

Upvotes: 1

Views: 2713

Answers (1)

Lesiak
Lesiak

Reputation: 26064

The error message is telling you that your method call is not a method call on a mock.

org.mockito.exceptions.misusing.MissingMethodInvocationException: 
when() requires an argument which has to be 'a method call on a mock'.
For example:
    when(mock.getArticles()).thenReturn(articles);

Why? Because you are trying to mock static method.

Mockito.when(mockBookSearch.returnFiveBooks(searchResults)).thenReturn(topFive);

which is equivalent to:

Mockito.when(BookSearch.returnFiveBooks(searchResults)).thenReturn(topFive);

Mockito cannot be used to mock static methods.

This explains the error you receive. But more fundamental problem with your code is that you have a method under test, and mock it in the test. This makes no sense. You should mock collaborators used by your method (there are no in your code). To test returnFiveBooks you don't need mocks at all:

@Test
public void returnFiveBooksFromSearchResults() {
    var topFive = BookSearch.returnFiveBooks(searchResults);
    assertEquals(topFive.size(), 5);
}

Edit: Mocking static methods is supported since Mockito 3.4.0

Upvotes: 1

Related Questions