I tried junit with mockito, and wrote some test cases for a coding exercise.
Here is the test case which i wrote:
@RunWith(SpringRunner.class)
public class TransactionControllerTest {
@Mock
TransactionService transactionServiceMock;
@InjectMocks
TransactionController transactionController;
TransactionRequest txn = new TransactionRequest("123.34", "2018-11-28T23:32:36.312Z");
@Test
public void testSaveTxn() throws Exception {
Mockito.when(transactionServiceMock.saveTxn(Mockito.any(TransactionRequest.class))).thenReturn(true);
ResponseEntity<?> responseEntity = transactionController.saveTxn(null, txn);
assertTrue(responseEntity.getStatusCode().equals(HttpStatus.CREATED));
}
@Test
public void testGetStats() throws Exception {
StatsResponse sr = new StatsResponse("0.00", "0.00", "0.00", "0.00", 0L);
Mockito.when(transactionServiceMock.getStats()).thenReturn(sr);
ResponseEntity<StatsResponse> responseEntity = (ResponseEntity<StatsResponse>) transactionController.getStats(null);
System.out.println("sr response = "+responseEntity.getBody());
assertTrue(responseEntity.getBody().equals(sr));
}
@Test
public void testDelete() throws Exception {
Mockito.doNothing().when(transactionServiceMock).delete();
ResponseEntity<HttpStatus> responseEntity = (ResponseEntity<HttpStatus>) transactionController.deleteTxn(null);
System.out.println("sr response = "+responseEntity.getBody());
assertTrue(responseEntity.getStatusCode().equals(HttpStatus.NO_CONTENT));
}
}
The test cases were working fine.
But my application was rejected specifying the following reason:
You were using SpringRunner even though you are not using SpringContext in the tests, and mocking everything.
Now, following are my concerns:
What's wrong with the test cases?
What is the meaning of above rejection reason?
How can i correct that?
What's wrong with the test cases?
I think what they want you to do is to write a spring web layer test. This is not a spring MVC test/spring-boot test. Because you don't test the controller as a spring loaded resource. You test it as a simple java class. That won't prove whether it behaves as a Spring controller correctly. You won't be able to test features such as;
How can i correct that?
You have to write a spring MVC test and use MockMvc
or RestTemplate
to verify your controller. For example;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = YourContext.class)
@WebAppConfiguration
public class MyWebTests {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
@Test
public void foo() throws Exception {
mockMvc.perform(get("/status"));
//and verification
}
}
Usage of mockito mocks is not the worst idea, but you could have used auto wired @MockBean
s.
If this is spring-boot, you will have more flexibility. Have a look at following resources.
https://docs.spring.io/spring/docs/current/spring-framework-reference/testing.html https://spring.io/guides/gs/testing-web/