0

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:

  1. What's wrong with the test cases?

  2. What is the meaning of above rejection reason?

  3. How can i correct that?

KayV
  • 12,987
  • 11
  • 98
  • 148

2 Answers2

1

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;

  • spring resource injection
  • request dispatching and validation

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 @MockBeans.

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/

Laksitha Ranasingha
  • 4,321
  • 1
  • 28
  • 33
0

You have complaint because you don't need spring's test features in your test. Your test is pure unit test.

So if you will remove @RunWith(SpringRunner.class) nothing will be changed for your test. Just put there @ExtendWith(MockitoExtension.class)

SpringRunner will initialize spring context for you test that you could inject or mock slice of your application using following annotations:

  • @MockBean
  • @Autowired
  • etc..
Igor Konoplyanko
  • 9,176
  • 6
  • 57
  • 100