단위별 테스트 작성
저번 글과 이어서 이번에는 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.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
이 의존성을 통해서 결과값을 확인할 수 있음.
import static org.mockito.Mockito.when;
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.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.when;
@WebMvcTest(controllers = UserApiController.class)
@AutoConfigureMockMvc(addFilters = false)
@ExtendWith(MockitoExtension.class)
class UserApiControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private UserBusiness userBusiness;
private final ObjectMapper objectMapper = new ObjectMapper();
@BeforeEach
void setUp() {
mockMvc = MockMvcBuilders.standaloneSetup(new UserApiController(userBusiness)).build();
}
@Test
void getUserByEmail() throws Exception {
// Mock the business method using when().thenReturn()
UserResponse userResponse = new UserResponse(1L,"Taehwan", "Taehwan@gmail.com", LocalDateTime.now(),LocalDateTime.now());
when(userBusiness.getUserByEmail("Taehwan@gmail.com")).thenReturn(userResponse);
mockMvc.perform(get("/api_user/Taehwan@gmail.com")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isAccepted())
.andExpect(jsonPath("$.userName").value("Taehwan"))
.andExpect(jsonPath("$.userEmail").value("Taehwan@gmail.com"));
}
@Test
void getUserByEmailTest() throws Exception{
LocalDateTime now = LocalDateTime.now();
String nowString = now.toString(); // ISO-8601 형식 문자열
UserResponse userResponse = new UserResponse(1L,"Taehwan", "Taehwan@gmail.com", now,now);
UserResponse userResponse2 = new UserResponse(2L,"Taehwan", "Taehwan@gmail.com", now,now);
List<UserResponse> userResponseList = List.of(userResponse2,userResponse);
when(userBusiness.findByUserNameAndCreatedAt("Taehwan",now)).thenReturn(userResponseList);
mockMvc.perform(get("/api_user/Taehwan/" + nowString)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isAccepted())
.andDo(print())
.andExpect(jsonPath("$[0].userName").value("Taehwan"))
.andExpect(jsonPath("$[0].userEmail").value("Taehwan@gmail.com"))
.andExpect(jsonPath("$[1].userName").value("Taehwan"))
.andExpect(jsonPath("$[1].userEmail").value("Taehwan@gmail.com"));
}
}
주요 어노테이션 및 클래스:
• @WebMvcTest: Spring MVC 컨트롤러를 테스트하는 데 사용됩니다. UserApiController만 로드하여 테스트합니다.
• @AutoConfigureMockMvc: MockMvc를 자동 구성합니다. addFilters = false는 보안 필터를 비활성화하여 인증 없이 테스트를 수행할 수 있게 합니다.
• @ExtendWith(MockitoExtension.class): Mockito 확장을 사용하여 Mockito의 애노테이션을 활성화합니다.
• @MockBean: Spring 애플리케이션 컨텍스트에 모킹된 빈을 추가합니다. UserBusiness를 모킹하여 테스트합니다.
클래스 필드:
• @Autowired MockMvc: MockMvc 인스턴스를 자동 주입하여 사용합니다.
• @MockBean UserBusiness:** UserBusiness를 모킹하여 테스트에서 사용할 수 있도록 합니다.
• ObjectMapper: JSON 직렬화 및 역직렬화를 위해 사용됩니다.
주요 기능 요약:
• MockMvc: HTTP 요청을 시뮬레이션하고 응답을 검증합니다.
• mockMvc.perform(): HTTP 요청을 시뮬레이션합니다.
• andExpect(): 응답 상태 코드와 JSON 응답 본문의 내용을 검증합니다.
• andDo(print()): 요청 및 응답 내용을 콘솔에 출력합니다.
mockMvc.perform 와 http.MediaType을 통해서
mockMvc.perform(get("/api_user/Taehwan/" + nowString)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isAccepted())
아래 이 구문을 실행 할 수 있는 것이다.
여기서 등장한 부분이
BDD (Behavior Driven Development)
코드보다 인간의 언어와 유사하게 구성되어야 한다.
BDD는 TDD를 수행하려는 어떤한 행동과 기능을 개발자가 더 이해하기 쉽게하는 것이 목적이다.
모든 테스트 문장은 Given When Then으로 나눠서 작성할 수 있어야 한다.
순수 Mockito에서 BDD의 Given/When/Then을 사용하기 위해서 다음과 같이 when(obj) 메서드와 thenReturn() 메서드를 이용하고 verity() 구문을 이용해 검증한다. 그렇기에 given then이 더 어울린다.
예시를 보면
given(Class.method()).willReturn()
이렇기 때문에 조금더 Given When Then과 비슷해진다.
반복문이있을때는
given(mockRepo.getOne(1L)).willReturn(new Object(1L));
given(mockRepo.getOne(2L)).willReturn(new Object(2L));
given(mockRepo.getOne(3L)).willReturn(new Object(3L));
given(mockRepo.getOne(anyLong()))
.willAnswer(id -> new Object(id)));
willAnswer을 통해서 람다 형식을 통해서 해결할 수 있다.
'Spring > Test' 카테고리의 다른 글
태태개발일지 - Service 계층 Test (0) | 2024.06.09 |
---|---|
태태개발일지 -TestCode 편 (0) | 2024.06.09 |