Search code examples
javajunit5junit-jupiter

JUnit 5 and Mockito assertThrows() raises NullPointerException instead of original


I want to test a method which should throw a exception of type MyCustomException. This is an example of my class MyService.

public class MyService {
    public void invoke(InvocationContext ctx) throws MyCustomException{
        if(ctx == null) {
            throw new MyCustomException("Parameter ctx must not be null.");
        }
    }
}

I would like to test, whether method throws MyCustomException if I pass a null value with the assertThrows().

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mockito;
import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
public class AxwApplicationTest {
    @Spy
    @InjectMocks
    MyService myServiceToTest;

    @Test
    public void invoke_ShouldThrow_MyCustomException() {
        assertThrows(MyCustomException.class, () -> {
            myServiceToTest.invoke(null);
        });
    }
}

Somehow the exception is thrown but ends up as NullPointerException and I don't know how to solve it. The assertThrows gives my following error:

java.lang.AssertionError: unexpected exception type thrown; expected:<com.myproject.MyCustomException> but was:<java.lang.NullPointerException>

Maven dependencies:

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <version>5.9.2</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>4.0.0</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-junit-jupiter</artifactId>
    <version>4.0.0</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-inline</artifactId>
    <version>4.0.0</version>
    <scope>test</scope>
</dependency>

Solution

  • the problem is the @InjectMocks and @Spy annotation. Using them together does not make sense (as discussed in this stackoverflow post). Creating the class by hand solves the NullPointerException and the test runs successfully

    import org.junit.jupiter.api.Test;
    import org.junit.jupiter.api.extension.ExtendWith;
    import org.mockito.InjectMocks;
    import org.mockito.Mockito;
    import org.mockito.Spy;
    import org.mockito.junit.jupiter.MockitoExtension;
    
    import static 
    org.junit.jupiter.api.Assertions.assertThrows;
    
    @ExtendWith(MockitoExtension.class)
    public class MyServiceTest {
       MyService myServiceToTest;
    
       @Test
       public void invoke_ShouldThrow_MyCustomException() {
          MyService myServiceToTest = new MyService();
          assertThrows(MyCustomException.class, () -> {
            myServiceToTest.invoke(null);
          });
       }
    }