Unit Testing in Spring Boot: DAO, Service, and Controller With the JDBC
Need help with unit testing?
Join the DZone community and get the full member experience.
Join For FreeIn this unit testing example with Spring Boot, I am going to useLabstatOutputReportDao
, LabstatService
, andLabstatController
.
For DAO:
@Transactional
means rollback on the transaction after testing. Additionally, @SpringBootTest
means that we are running unit testing with the Spring Boot feature.
Note: for DAO, we directly connect to DB for testing.
@RunWith(SpringRunner.class)
@Transactional
@SpringBootTest
public class LabstatOutputReportDaoTest {
private static final Logger log = LoggerFactory.getLogger(LabstatOutputReportDaoTest.class);
@Autowired
ILabstatOutputReportDao labOutputDao;
@Test
public void getAllLabOutputTest() {
log.info("LabstatOutputReportDaoTest::getAllLabOutputTest()");
if(labOutputDao.getAllLabOutput().isPresent()) {
List<Map<String, Object>> actualList = labOutputDao.getAllLabOutput().get();
assertThat(actualList).isNotNull();
}
}
}
For service, we are using Mokito for mocking beans. We use @MockBean
for mocking the DAO. And then, we use @TestConfiguration
to provide a mock bean for the service.
@RunWith(SpringRunner.class)
public class LabstatServiceTest {
private static final Logger log = LoggerFactory.getLogger(LabstatServiceTest.class);
@TestConfiguration
static class LAUSUtilityServiceTestConfiguration{
@Bean
public LabstatService labstatService() {
return new LabstatService();
}
}
@MockBean
private ILabstatOutputReportDao labstatOutputReportDao;
@Autowired
private LabstatService labstatSrvc;
@Before
public void setUp() throws SQLException {
Mockito.when(labstatOutputReportDao.getAllLabOutput()).thenReturn(getAllLabOutputMockReturn());
}
@Test
public void getAllLabOutputTest() {
log.info("unit test getAllLabOutputTest()...");
int actSize = labstatSrvc.getAllLabOutput().size();
int expSize = 2;
assertThat(actSize).isEqualTo(expSize);
}
private Optional<List<Map<String, Object>>> getAllLabOutputMockReturn(){
List<Map<String, Object>> list = new ArrayList<>();
list = IntStream.range(1, 3).mapToObj((idx) ->{
Map<String, Object> map = new HashMap<>();
map.put(String.valueOf(idx), "TASKNUM"+idx*10);
return map;
}).collect(Collectors.toList());
return Optional.ofNullable(list);
}
For the controller, we will be using @wemvctest
for controller testing. Additionally, we will be using jsonPath
for testing return if return as:
@RunWith(SpringRunner.class)
@WebMvcTest(value = LabstatController.class, secure = false)
public class LabstatControllerTest {
private static final Logger log = LoggerFactory.getLogger(LabstatControllerTest.class);
@Autowired
private MockMvc labMVc;
@MockBean
private LabstatService labstatSrvc;
@Before
public void setup() {
Mockito.when(labstatSrvc.getAllStates()).thenReturn(getAllStatesServiceMockReturn());
}
@Test
public void testLabCtrlGetStates() throws Exception {
// add more testing realted to json return in controller later on
log.info("unit testing controller testLabCtrlGetStates()...");
labMVc.perform(MockMvcRequestBuilders.get("/rest/v1/public/getSPData").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
// test the first data in states should be st1
.andExpect(jsonPath("$.states.states[0].name", is("st1")));
}
private Map<String, Object> getAllStatesServiceMockReturn() {
Map<String, Object> stateMap = new HashMap<>();
List<State> stateList = new ArrayList<>();
for (int i = 1; i < 10; i++) {
State tmpST = new State();
tmpST.setAreaseq(i);
tmpST.setBlsRegion(i);
tmpST.setName("st" + i);
tmpST.setStateCode(String.valueOf(10 + i));
tmpST.setStateNum(String.valueOf(100 + i));
stateList.add(tmpST);
}
stateMap.put("states", stateList);
return stateMap;
}
}
Happy testing!
Opinions expressed by DZone contributors are their own.
Comments