Konstantin
Konstantin

Reputation: 65

Mockito: verify a method with exception called multiple times

Could anyone advise on the following? I have a method that throws an exception if nothing found in the database and this is business requirement. Also, method has retry implemented via Spring xml AOP. So that, the method should run several times and then fail with exception. Is there any way to use Mockito for to count the number of times the method was called?

This one doesn't work:

verify(mock, times(5)).method();

Because the final method invocation throws exception and this exception fails the verifying itself. I tried @Test(expected = ...) but it just catches the final exception and skips verification.

Upvotes: 0

Views: 1248

Answers (1)

Bodo Teichmann
Bodo Teichmann

Reputation: 121

Consider:

    package de.test;
    public class MyService {
      int invocations = 0;
      public void doSomething(int x){
        invocations++;
        if (invocations==5){
          throw new RuntimeException("exception");
        }
        return;
      };
    }

    package de.test;
    
    public class MyProcessor {
      private MyService myService;
    
      public MyProcessor(MyService myService) {
        this.myService = myService;
      }
    
      public void process(int n) {
        myService.doSomething(n);
        System.out.println("Processed: " + n);
      }
    }

And this Testcode:

  package de.test;
    
  import de.bodo.MyProcessor;
  import de.bodo.MyService;
  import org.junit.jupiter.api.Test;
  import org.mockito.Mockito;
    
  public class ProcessorTest {

    @Test
    public void processTest() {
      MyService myService = Mockito.spy(new MyService());
      MyProcessor myProcessor = new MyProcessor(myService);
      
      myProcessor.process(0);
      myProcessor.process(1);
      myProcessor.process(2);
      myProcessor.process(2);
      RuntimeException thrown = assertThrows( RuntimeException.class,
         ()-> myProcessor.process(2),
         " expected exception" );
      myProcessor.process(2);
    
      Mockito.verify(myService, Mockito.atMostOnce()).doSomething(0);
      Mockito.verify(myService, Mockito.atMostOnce()).doSomething(1);
      Mockito.verify(myService, Mockito.atMost(4)).doSomething(2);
      Mockito.verify(myService, Mockito.atLeastOnce()).doSomething(1);
      Mockito.verify(myService, Mockito.atLeast(2)).doSomething(2);
      Mockito.verify(myService, Mockito.times(4)).doSomething(2);
      Mockito.verify(myService, Mockito.never()).doSomething(3);    
    }
  }

So you can not only check how often a method was called, but even you can count how often a method was call with one specific argument (the integer number in this example.)

You need to add Mockito to your pom.xml:


        !-- https://mvnrepository.com/artifact/org.mockito/mockito-junit-jupiter -->
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-junit-jupiter</artifactId>
            <version>4.8.1</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.mockito/mockito-core -->
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>4.8.1</version>
            <scope>test</scope>
        </dependency>

Source: https://www.logicbig.com/tutorials/unit-testing/mockito/verifying-varing-number-of-invocations.html

Upvotes: 2

Related Questions