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

scott :

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?

ernest_k :

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.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=35802&siteId=1