Mockito – when() requires an argument which has to be ‘a method call on a mock’
Run the following Spring Boot + JUnit 5 + Mockito integration test.
package com.mkyong.core.services;
import com.mkyong.core.repository.HelloRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.springframework.boot.test.context.SpringBootTest;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;
@SpringBootTest
public class HelloServiceMockTest {
@Mock
private HelloRepository helloRepository;
@InjectMocks // auto inject helloRepository
private HelloService helloService = new HelloServiceImpl();
@BeforeEach
void setMockOutput() {
when(helloService.getDefault()).thenReturn("Hello Mockito");
}
//...
}
But hits the following errors:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);
Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
Those methods <strong>cannot</strong> be stubbed/verified.
Mocking methods declared on non-public parent classes is not supported.
2. inside when() you don't call method on mock but on some other object.
Solution
This when(mock.getArticles()).thenReturn(articles);
need to apply on mocked object. When Mockito see this @InjectMocks
, it doesn’t mock it, it just creates a normal instance, so the when()
will be failed.
To solve it, annotate @spy
to mock it partially.
package com.mkyong.core.services;
import com.mkyong.core.repository.HelloRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Spy;
import org.springframework.boot.test.context.SpringBootTest;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;
@SpringBootTest
public class HelloServiceMockTest {
@Mock
private HelloRepository helloRepository;
@Spy // mock it partially
@InjectMocks
private HelloService helloService = new HelloServiceImpl();
@BeforeEach
void setMockOutput() {
when(helloService.getDefault()).thenReturn("Hello Mockito");
}
//...
}
Still i am getting the same error as mentioned above .Can you please help
still same error is happening
Still the same error showing up
It worked, but is it okay to use both @Spy and @InjectMocks together?
it worked for me, thanks