I have an interface(Client) with two implementation classes PClient and SClient respectively.
Interface - Client
Impl class - PCleint, SClient
I have a controller in which both the impl classes are autowired using qualifier spring boot annotation. Now i need to write JUNIT mockito test case for the controller.
I am not sure how to mock the different Impl classes which has the same interface. I tried mocking in the following way but it throws null pointer exception in the stub method of the respective mocks.
@Mock
private Client pclient
@Mock
private Client sclient
How do i differentiate mocking different impl classes such that the methods of the impl classes are called. Should i do like the below.
@Mock
private PClient pclient
@Mock
private SClient sclient
It did not work for me . Either one throws null pointer exception . Please advise.
I guess the tricks are you need to use Before
to stub the return value and use @InjectMocks
for the controller.
Since @Mock
won't return a "real" object, it just return a "mock"(or fake:P ) one. So when you call a method of this "mock" object, it won't return the actual output from your method, instead it gives back null
. That's why you need to stub the return with @Before
.
See my example code below:
Client Interface
public interface Client {
String someMethod();
}
Class implemented
public class PClient implements Client {
private static final String name = "PClient";
@Override
public String someMethod() {
return name;
}
}
public class SClient implements Client{
private static final String name = "SClient";
@Override
public String someMethod() {
return name;
}
}
The Client Controller
@Controller public class ClientController {
@Autowired
private PClient pClient;
@Autowired
private SClient sClient;
public ClientController(){
}
public String executePClient(){
return this.pClient.someMethod();
}
public String executeSClient(){
return this.sClient.someMethod();
}
public String execute(Client client){
return client.someMethod();
}
}
The test case You need to add a @Before
to stub the method return.
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class ClientControllerTest {
@Mock
private PClient pclient;
@Mock
private SClient sclient;
@InjectMocks
private ClientController clientController;
@Before
public void setup(){
when(pclient.someMethod()).thenReturn(new PClient().someMethod());
when(sclient.someMethod()).thenReturn(new SClient().someMethod());
}
@Test
public void testPClient(){
String result = clientController.executePClient();
assertEquals("PClient",result);
}
@Test
public void testSClient(){
String result = clientController.executeSClient();
assertEquals("SClient",result);
}
@Test
public void testExecuteWithPClient(){
String result = clientController.execute(pclient);
assertEquals("PClient",result);
}
@Test
public void testExecuteWithSClient(){
String result = clientController.execute(sclient);
assertEquals("SClient",result);
}
}
Result: Tests passed: 4 of 4 tests - 31ms