I am using @RunWith(SpringRunner.class)
to writing unit test case to mock the object. I am trying to mock the repository instance which is accepting request object and returning response, but in unit test case implementation I have mocked the repository using @MockBean
annotation and register the it's method call using Mockito.when(respository.post(request)).thenReturn(response)
. But this call is returning null
.
If a method return type is a custom class, a mock returns null because there is no empty value for a custom class. RETURN_MOCKS will try to return mocks if possible instead of null . Since final class cannot be mocked, null is still returned in that case.
Mockito allows us to partially mock an object. This means that we can create a mock object and still be able to call a real method on it. To call a real method on a mocked object we use Mockito's thenCallRealMethod().
Spring Boot's @MockBean AnnotationThe mock will replace any existing bean of the same type in the application context. If no bean of the same type is defined, a new one will be added. This annotation is useful in integration tests where a particular bean, like an external service, needs to be mocked.
Mockito @Mock Annotation We can mock an object using @Mock annotation too. It's useful when we want to use the mocked object at multiple places because we avoid calling mock() method multiple times. The code becomes more readable and we can specify mock object name that will be useful in case of errors.
I faced similar situation, the problem is given parameter in Mockito.when()
block may not be the same as spring generated. I'll explain my case below, hope to help you:
Product product = new Product(..);
Mockito.when(service.addProduct(product)).thenReturn(saveProduct)
When I send a request, spring generates new Project object which has same fields with product
but instance is different. That is, Mockito cannot catch when
statement. I changed it like below and it's worked:
Mockito.when(service.addProduct(Mockito.any())).thenReturn(savedProduct)
I figured it out. But the solution is still weird to me...
I was facing this issue because, I was instantiating the request
and response
in @Before
annotated method... as describing below.
@Before
public void setup() {
Request reqA = new Request();
reqA.set..(..);
Response res = new Response();
res.set..(..);
Mockito.when(this.respository.post(reqA)).thenReturn(res);
}
@Test
public void test() {
// Creating Request instance again with all same properties.
// Such that this req instance is technically similarly as instantiated in @Before annotated method (above).
// By, implementing the equals and hashCode method.
Request reqB = new Request();
reqB.set..(..);
// Getting res as 'null' here....
Response res = this.service.post(reqB);
}
Since, reqA
and reqB
are technically similar then why mocked call not returning the same response as registered.
If I moved setup()
method code inside test()
method every thing starts working !!!!!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With