카테고리 없음

#108. Service, Controller 및 통합 테스트 코드

열하나요 2023. 12. 8. 11:04

1. Service 테스트

package com.kh.boot.job.model.service;

import java.util.List;

import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;

import com.kh.boot.job.model.dao.JobInterviewMapper;
import com.kh.boot.job.model.vo.JobInterview;

import lombok.extern.slf4j.Slf4j;

@RunWith(SpringRunner.class)
@Slf4j
@Transactional
@SpringBootTest
public class JobInterviewServiceTest {
	
	@Autowired
	JobInterviewService jobInterviewService; // 의존관계
	
	@Autowired
	JobInterviewMapper jobInterviewMapper;
	
	@Test
	public void jobInterviewServiceTest() {
		
		// ----- given
		JobInterview gunhee = JobInterview.builder()
										  .company("큰회사")
										  .name("김건희")
										  .interviewer("채감독")
										  .build();
		
		// ----- when
		jobInterviewService.insert(gunhee);
		
		List<JobInterview> jobList = jobInterviewService.selectAll();
		
		// ----- then
		JobInterview gh = jobList.get(1);
		
		log.info("추가된 새로운 건희씨가 가고싶은 회사 : {}", gh.getCompany());
		log.info("추가된 새로운 건희씨의 이름 : {}", gh.getName());
		log.info("추가된 새로운 건희씨의 면접관 : {}", gh.getInterviewer());

	}
}

 

 

2. Controller

@RestController
@RequestMapping("/job")
@RequiredArgsConstructor
public class JobInterviewController {
	
	private final JobInterviewService jobInterviewService;
	
	@GetMapping("/test")
	public String Method(String param, String id) {
		return id;
	}
	// 테스트 끝
	
}

 

테스트

package com.kh.boot.job.controller;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;

import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import com.kh.boot.board.model.service.BoardService;
import com.kh.boot.idol.model.service.IdolService;
import com.kh.boot.job.model.service.JobInterviewService;

import lombok.extern.slf4j.Slf4j;

@RunWith(SpringRunner.class) // BOOT랑 JUNIT을 연결해주는 애노테이션
@Slf4j // logback이용해서 log를 찍기 위한 롬복애노테이션
@WebMvcTest // Controller에서 Test할 때 사용하는 애노테이션 (요청보내고 응답받는 Controller의 Test)
public class JobInterviewControllerTest {
	
	@Autowired
	private MockMvc mvc; // 웹 API테스트 할 때 MockMvc타입을 이용해서 테스트 수행
	
	// 가짜로 객체를 만들어서 테스트 수행(?) => 얘네가 없으면 테스트 수행이 안됨
	@MockBean
	JobInterviewService jobInterviewService;
	@MockBean
	BoardService boardService;
	@MockBean
	IdolService idolService;
	
	
	@Test
	public void apiTest() throws Exception {
		
		/*
		mvc.perform(get("/job/test"))
		   .andExpect(content().string("하이"))
		   .andDo(print());
		*/
		// perform()
		// 요청을 전송하는 역할을 하는 메소드
		// get("/url")
		// post("/url")
		// put("url")
		// delete("/url") => MockMvcRequestBuilder를 반환해주는 정적메소드
		
		// andExpect() => 요청의 결과로 예상되는 응답값을 지정해서 테스트를 진행할 수 있음
		// content.타입() => 응답데이터를 검증
		// isOk() : 200
		// isNotFound() : 404
		// isMethodNotAllowed() : 405
		// isInternalServerError() : 500
		
		MultiValueMap<String, String> map = new LinkedMultiValueMap();
		map.add("param", "하이");
		map.add("id", "최강김건희");
		
		
		mvc.perform(get("/job/test").params(map))
		   .andDo(print()) // 요청 / 응답 전체 메시지 확인
		   .andExpect(content().string("최강김건희"));
		
		// param(MultiValueMap)
		// 키 = 값의 파라미터를 전달할 수 있음
		// 여러 개일 때는 params(), 하나일 때는 param()
		
	}
}

 

3. 통합테스트

controller

package com.kh.boot.job.controller;

import java.nio.charset.Charset;
import java.util.List;

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.kh.boot.job.model.service.JobInterviewService;
import com.kh.boot.job.model.vo.JobInterview;

import lombok.RequiredArgsConstructor;

@RestController
@RequestMapping("/job")
@RequiredArgsConstructor
public class JobInterviewController {
	
	private final JobInterviewService jobInterviewService;
	
	/*
	@GetMapping("/test")
	public String Method(String param, String id) {
		return id;
	}
	// 테스트 끝
	*/
	
	// 통합
	@GetMapping
	public ResponseEntity<List<JobInterview>> selectAll(){
		List<JobInterview> jobList = jobInterviewService.selectAll();
		HttpHeaders header = new HttpHeaders();
		header.setContentType(new MediaType("application", "json", Charset.forName("UTF-8")));
		return new ResponseEntity<List<JobInterview>>(jobList, header, HttpStatus.OK);
	}
	
	@PostMapping
	public ResponseEntity<String> insert(@RequestBody JobInterview jobInterview){
		String result = jobInterviewService.insert(jobInterview) > 0 ? "success" : "fail";
		HttpHeaders header = new HttpHeaders();
		header.setContentType(new MediaType("html", "text", Charset.forName("UTF-8")));
		return new ResponseEntity<String>(result, header, HttpStatus.OK);
		/*
		// AJAX로 요청으로 보내서
		// 요청 바디에 JSON형태로 데이터가 들어올 것
		{
			"company" : "머시기 회사",
			"name" : "김건희",
			"interviewer" : "누구누구"
		}
		*/
	}

}

 

JobFullTest.java

package com.kh.boot.job;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.transaction.annotation.Transactional;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.kh.boot.job.model.vo.JobInterview;

import lombok.extern.slf4j.Slf4j;

@RunWith(SpringRunner.class)
@Slf4j
@SpringBootTest
@AutoConfigureMockMvc
// @WebMvcTest 애노테이션을 사용하지 않는 경우
// @SpringBootTest 애노테이션을 사용하는데 MockMvc도 함께 서야할 때 사용하는 애노테이션
@Transactional
public class JobFullTest {
	
	@Autowired
	private MockMvc mvc;
	
	@Autowired
	private ObjectMapper objectMapper;
	
	@Test
	public void fullTest() throws Exception {
		
		JobInterview in = JobInterview.builder()
									  .company("집")
									  .name("건희씨")
									  .interviewer("이땡철")
									  .build();
		
		// log.info(in.toString());
		
		log.info("------------------------------------절취선----------------------------------------");
		
		String gunhee = objectMapper.writeValueAsString(in);
		// Gson 라이브러리 와 양대산맥을 이루는 Jackson Databind => 근데 얘는 Spring Boot에 내장되어 있음
		
		log.info(gunhee);
		
		mvc.perform(post("/job").content(gunhee)
								.contentType(MediaType.APPLICATION_JSON)
								.accept(MediaType.APPLICATION_JSON))
		   .andExpect(status().isOk())
		   .andDo(print());
		// 오류 => JSON타입으로 보내야 하는데 객체타입으로 보냄 => 바꿔줘야 함 => ObjectMapper
		
		log.info("------------------------------------절취선----------------------------------------");
		
		mvc.perform(get("/job")).andDo(print());
		
	}
}