I'm trying to mock a service using Mockito and setting up all the method invocations in a @BeforeAll method. The code is the following:
@SpringBootTest
@AutoConfigureMockMvc(addFilters = false)
public class VirtualMachineServiceIntegrationTests {
@MockBean
static VirtualMachineService virtualMachineService;
@Autowired
private MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
static String courseId;
static String studentId;
static Long teamId;
static Long vmId;
static SystemImage os;
static VirtualMachineDTO virtualMachineDTO;
static ConfigurationDTO configurationDTO;
@BeforeAll
static void beforeAll() {
studentId = "student";
courseId = "course";
teamId = 1L;
vmId = 1L;
os = SystemImage.WINDOWS_10;
virtualMachineDTO = VirtualMachineDTO.builder()
.id(1L)
.num_vcpu(2)
.disk_space(1000)
.ram(4)
.status(VirtualMachineStatus.OFF)
.build();
configurationDTO = ConfigurationDTO.builder()
.id(1L)
.min_vcpu(2)
.min_disk(1000)
.min_ram(4)
.max_vcpu(12)
.max_disk(2000)
.max_ram(16)
.max_on(4)
.tot(20)
.build();
Mockito.when(Mockito.any(VirtualMachineService.class).createVirtualMachine(Mockito.anyString(), Mockito.anyLong(), Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt())).thenReturn(virtualMachineDTO);
}
}
The NPE is throwed by Mockito even without the thenReturn
method. If I move this line
Mockito.when(Mockito.any(VirtualMachineService.class).createVirtualMachine(Mockito.anyString(), Mockito.anyLong(), Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt())).thenReturn(virtualMachineDTO);
inside a @Test method then, after throwing a NPE, it will output this:
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Misplaced or misused argument matcher detected here:
-> at it.polito.ai.backend.VirtualMachineServiceIntegrationTests.createVirtualMachine(VirtualMachineServiceIntegrationTests.java:87)
-> at it.polito.ai.backend.VirtualMachineServiceIntegrationTests.createVirtualMachine(VirtualMachineServiceIntegrationTests.java:87)
-> at it.polito.ai.backend.VirtualMachineServiceIntegrationTests.createVirtualMachine(VirtualMachineServiceIntegrationTests.java:87)
-> at it.polito.ai.backend.VirtualMachineServiceIntegrationTests.createVirtualMachine(VirtualMachineServiceIntegrationTests.java:87)
-> at it.polito.ai.backend.VirtualMachineServiceIntegrationTests.createVirtualMachine(VirtualMachineServiceIntegrationTests.java:87)
-> at it.polito.ai.backend.VirtualMachineServiceIntegrationTests.createVirtualMachine(VirtualMachineServiceIntegrationTests.java:87)
-> at it.polito.ai.backend.VirtualMachineServiceIntegrationTests.createVirtualMachine(VirtualMachineServiceIntegrationTests.java:87)
You cannot use argument matchers outside of verification or stubbing.
Examples of correct usage of argument matchers:
when(mock.get(anyInt())).thenReturn(null);
doThrow(new RuntimeException()).when(mock).someVoidMethod(anyObject());
verify(mock).someMethod(contains("foo"))
This message may appear after an NullPointerException if the last matcher is returning an object
like any() but the stubbed method signature expect a primitive argument, in this case,
use primitive alternatives.
when(mock.get(any())); // bad use, will raise NPE
when(mock.get(anyInt())); // correct usage use
Also, this error might show up because you use argument matchers with methods that cannot be mocked.
Following methods *cannot* be stubbed/verified: final/private/equals()/hashCode().
Mocking methods declared on non-public parent classes is not supported.
I'm new at Spring testing and Mockito so I cannot figure it out what I'm doing wrong. Any help appreciated, thanks.
There are multiple things a bit strange here. The main/misunderstanding problem is:
Mockito#when is used to tell a concrete mock what to do on specific method call. So normally it goes something like this:
Mockito.when(mock.doSomeThings(anyString()).thenReturn("whatever");
Applying this pattern to your code, this should do the trick:
Mockito.when(virtualMachineService.createVirtualMachine(Mockito.anyString(), Mockito.anyLong(), Mockito.anyString(), Mockito.any Int(), Mockito.anyInt(), Mockito.anyInt())).thenReturn(virtualMachineDTO);
Besides this, it looks strange to that you declared everything as static.
I would remove static from all class members and change @BeforeAll
to @Before
or @BeforeEach
(depending on if you use JUnit 4 or 5).