Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring boot mocked object returning null on call

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.

like image 295
vsk.rahul Avatar asked May 08 '18 01:05

vsk.rahul


People also ask

Why is mock method 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.

Can you call method on mocked object?

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().

What is MockBean annotation?

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.

What does mockito@ mock do?

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.


2 Answers

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)
like image 62
farukcankaya Avatar answered Oct 23 '22 09:10

farukcankaya


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 !!!!!

like image 20
vsk.rahul Avatar answered Oct 23 '22 10:10

vsk.rahul