Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the point of verifying the number of times a function is called with Mockito?

In my understanding, code testing is to test whether results are right, like a calculator, I need to write a test case to verify if the result of 1+1 is 2.

But I have read many test cases about verifying the number of times a method is called. I'm very confused about that. The best example is what I just saw in Spring in Action:

public class BraveKnight implements Knight {
    private Quest quest;
    public BraveKnight(Quest quest) { 
        this.quest = quest; 
    }
    public void embarkOnQuest() {
        quest.embark(); 
    }
}

public class BraveKnightTest {
    @Test 
    public void knightShouldEmbarkOnQuest() { 
        Quest mockQuest = mock(Quest.class); 
        BraveKnight knight = new BraveKnight(mockQuest); 
        knight.embarkOnQuest(); 
        verify(mockQuest, times(1)).embark(); 
    }
}

I really have no idea about why they need to verify the embark() function is called one time. Don't you think that embark() will certainly be invoked after embarkOnQuest() is called? Or some errors will occur, and I will notice error messages in the logs, which show the error line number, that can help me quickly locate the wrong code.

So what's the point of verifying like above?

like image 353
scott Avatar asked Sep 07 '18 12:09

scott


People also ask

What is the use of Verify in Mockito?

Mockito verify() method can be used to test number of method invocations too. We can test exact number of times, at least once, at least, at most number of invocation times for a mocked method. We can use verifyNoMoreInteractions() after all the verify() method calls to make sure everything is verified.

How do you verify that void methods were called using Mockito?

Using the verify() Method Mockito provides us with a verify() method that lets us verify whether the mock void method is being called or not. It lets us check the number of methods invocations. So, if the method invocation returns to be zero, we would know that our mock method is not being called.

Which method in Mockito verifies that no interaction has happened with a mock in Java?

Mockito verifyZeroInteractions() method It verifies that no interaction has occurred on the given mocks. It also detects the invocations that have occurred before the test method, for example, in setup(), @Before method or the constructor.

What is the purpose of assertArrayEquals message AB?

7. What is the purpose of assertArrayEquals(“message”, A, B)? Explanation: Asserts the equality of the A and B arrays.


2 Answers

The need is simple: to verify that the correct number of invocations were made. There are scenarios in which method calls should not happen, and others in which they should happen more or less than the default.

Consider the following modified version of embarkOnQuest:

public void embarkOnQuest() {
    quest.embark(); 
    quest.embarkAgain(); 
}

And suppose you are testing error cases for quest.embark():

@Test 
public void knightShouldEmbarkOnQuest() { 
    Quest mockQuest = mock(Quest.class); 
    Mockito.doThrow(RuntimeException.class).when(mockQuest).embark();
    ...
}

In this case you want to make sure that quest.embarkAgain is NOT invoked (or is invoked 0 times):

verify(mockQuest, times(0)).embarkAgain(); //or verifyZeroInteractions

Of course this is one other simple example. There are many other examples that could be added:

  • A database connector that should cache entries on first fetch, one can make multiple calls and verify that the connection to the database was called just once (per test query)
  • A singleton object that does initialization on load (or lazily), one can test that initialization-related calls are made just once.
like image 167
ernest_k Avatar answered Oct 13 '22 09:10

ernest_k


Consider the following code:

public void saveFooIfFlagTrue(Foo foo, boolean flag) {
    if (flag) {
        fooRepository.save(foo);
    }
}

If you don't check the number of times that fooRepository.save() is invoked , then how can you know whether this method is doing what you want it to?

This applies to other void methods. If there is no return to a method, and therefore no response to validate, checking which other methods are called is a good way of validating that the method is behaving correctly.

like image 41
Ben Green Avatar answered Oct 13 '22 10:10

Ben Green