Issue
I have created an example below to test if Mockito is able to mock the method and return my value but it does not work. Here are the classes.
package com.te;
public interface IA {
Long getVal(Long v);
}
package com.te;
public class A implements IA{
@Override
public Long getVal(Long v) {
return 1L;
}
package com.te;
public class AService {
public void ser(){
A a = new A();
boolean d = a.getVal(1L) > 0;
if(d){
System.out.println("Inside If");
}
}}
import com.te.A;
import com.te.AService;
import com.te.IA;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class ATest {
@Test
public void test(){
IA a = Mockito.mock(A.class);
AService s = new AService();
Mockito.when(a.getVal(1l)).thenReturn(0L);
s.ser();
}}
In my Test class I am mocking the method and asking it to return 0 but it still returns 1 from the method. I am not sure why its not working and I tried to search but couldn't find anything. Please help me understand where I am incorrect here. Thanks.
Solution
The reason why it is not working is that IA
instance that you created using IA a = Mockito.mock(A.class);
is different from the one that ser
method is using.
Every time you make a call to ser
, it is creating its own new IA instance but not using the mocked one.
To make classes testable, it would be better to inject the dependencies rather than creating them using new keyword within code.
package com.te;
public class AService {
private IA a;
public AService(IA a) {
this.a = a;
}
public void ser(){
boolean d = a.getVal(1L) > 0;
if(d){
System.out.println("Inside If");
}
}}
Test
@Test
public void test(){
IA a = Mockito.mock(A.class);
AService s = new AService(a);
Mockito.when(a.getVal(1l)).thenReturn(0L);
s.ser();
}}
Answered By - Manohar Kotapati
Answer Checked By - Katrina (JavaFixing Volunteer)