For What

When we developing a project and serving for the user with a lot of function. And some of this function is called in multiple place. when a new requirement is come which need to modify the code of the old function. How can you ensure the ensure old function won’t be broken by the change you make. human test? too native. Human always make mistake. So we need the machine to check for us.

Layer Test (Deprecate)

we use mockito to mock all the dependencies injected (the database, the third party api) to the layer, in the Controller layer , we mock the Service function, in the Service layer, we mock the Dao function;


Controller:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27



@Test

public void testAddEmployee(){

MockHttpServletRequest request = new MockHttpServletRequest();

RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request));

when(employeeDAO.addEmployee(any(Employee.class))).thenReturn(true);

Employee employee =new Employee(1,"Lokesh", "Gupta","howtodoinjava@gmail.com");

ResponseEntity<Object> responseEntity = employeeController.addEmployee(employee);

assertThat(responseEntity.getStatusCodeValue()).isEqualTo(201);

assertThat(responseEntity.getHeaders().getLocation().getPath()).isEqualTo("/1");



}




Service:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21



@Test

public void getEmployeeByIdTest(){

when(dao.getEmployeeById(1)).thenReturn(new EmployeeVO(1,"Lokesh","Gupta","user@email.com"));

EmployeeVO emp = manager.getEmployeeById(1);

assertEquals("Lokesh", emp.getFirstName());

assertEquals("Gupta", emp.getLastName());

assertEquals("user@email.com", emp.getEmail());

}




Conclusion

Good: only test the necessary part.

Bad: it take a lot of effort for all the layer for same functionality.

Example:

https://howtodoinjava.com/spring-boot2/testing/rest-controller-unit-test-example/

https://howtodoinjava.com/spring-boot2/testing/spring-boot-mockito-junit-example/

Integration Test : TestContainer + SQL Initialization (Better)

Because the Layer Test is cause a lot of effort, so it is easy to give up. and then the Integration test came out

Integration test can test different modules are bounded correctly and if they work as expected in only one test case, no need to write for different layer , save a lot of effort.

**Integration test can more similar as the prod by using the testContainer or embedded db(H2).**

Integration test can test for certain behaviors by using the @sql to initial to test data to db.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21



@Sql{("schema.sql","data.sql"})

@Test

public void testAllEmployees(){

assertTrue(

this.restTemplate

.getForObject("[http://localhost:](http://localhost/)"+ port +"/employees", Employees.class)

.getEmployeeList().size() == 3);

}




Conclusion

integration test is a better choice

Example:

https://howtodoinjava.com/spring-boot2/testing/spring-integration-testing/