문제 : Run Tests in “blog.test” 했을 때, 계속 오류가 떴음

해결 방안
1. master branch
로 오면서 .properties
에 dev
로 안 고쳤음
master branch
로 오면서 .properties
에 dev
로 안 고쳤음spring.profiles.active=dev

2. LogFilter에 userAgent
가 null
일 경우 빈 문자열 ""
로 대체해주는 코드 입력 안 했음 (왜? 위치 몰라서, 잘 기억해두기)
userAgent
가 null
일 경우 빈 문자열 ""
로 대체해주는 코드 입력 안 했음 (왜? 위치 몰라서, 잘 기억해두기)package shop.mtcoding.blog._core.filter;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
@Slf4j
public class LogFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) servletRequest;
String uri = req.getRequestURI();
String ip = req.getRemoteAddr();
String userAgent = req.getHeader("User-Agent");
userAgent = userAgent == null ? "" : userAgent;
String msg = "[로그] ${uri} | IP: ${ip} | UA: ${ua}"
.replace("${uri}", uri)
.replace("${ip}", ip)
.replace("${ua}", userAgent);
log.info(msg);
filterChain.doFilter(servletRequest, servletResponse);
}
}

3. 어쩌다가 join_username_uk_fail_test 부분이 중복이었는데, 중복인 줄 모르고 오류 라고만 생각해서 삭제를 안 했었음
중복이었던 코드
@Test
public void join_username_uk_fail_test() throws Exception { // 이 메서드를 호출한 주체에게 예외 위임 -> 지금은 jvm 이다
// given -> 가짜 데이터
UserRequest.JoinDTO reqDTO = new UserRequest.JoinDTO();
reqDTO.setEmail("ssar@nate.com");
reqDTO.setPassword("1234");
reqDTO.setUsername("ssar");
String requestBody = om.writeValueAsString(reqDTO);
// System.out.println(requestBody); // {"username":"haha","password":"1234","email":"haha@nate.com"}
// when -> 테스트 실행
ResultActions actions = mvc.perform( // 주소가 틀리면 터지고, json 아닌거 넣으면 터지고, 타입이 달라도 터지고. 따라서 미리 터진다고 알려줌
MockMvcRequestBuilders
.post("/join")
.content(requestBody)
.contentType(MediaType.APPLICATION_JSON)
);
// eye -> 결과 눈으로 검증
String responseBody = actions.andReturn().getResponse().getContentAsString();
//System.out.println(responseBody); // {"status":200,"msg":"성공","body":{"id":4,"username":"haha","email":"haha@nate.com","createdAt":"2025-05-13 11:45:23.604577"}}
// then -> 결과를 코드로 검증 // json의 최상위 객체를 $ 표기한다
actions.andExpect(MockMvcResultMatchers.jsonPath("$.status").value(400));
actions.andExpect(MockMvcResultMatchers.jsonPath("$.msg").value("중복된 유저네임이 존재합니다"));
actions.andExpect(MockMvcResultMatchers.jsonPath("$.body").value(Matchers.nullValue()));
}
수정한 코드
package shop.mtcoding.blog.integre;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.transaction.Transactional;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import shop.mtcoding.blog.MyRestDoc;
import shop.mtcoding.blog._core.util.JwtUtil;
import shop.mtcoding.blog.user.User;
import shop.mtcoding.blog.user.UserRequest;
import static org.hamcrest.Matchers.matchesPattern;
// 5. (컨트롤러 가기) 문서 만들기 (상속하고, mvc 부모 옮기고, 부모에 갔으니 삭제하고, andDO 설정하고)
@Transactional
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK) // MOCK -> 가짜 환경을 만들어 필요한 의존관계를 다 메모리에 올려서 테스트
public class UserControllerTest extends MyRestDoc {
@Autowired
private ObjectMapper om; // json <-> java Object 변환 해주는 객체. IoC에 objectMapper가 이미 떠있음
private String accessToken;
@BeforeEach
public void setUp() {
// 테스트 시작 전에 실행할 코드
System.out.println("setUp");
User ssar = User.builder()
.id(1)
.username("ssar")
.build();
accessToken = JwtUtil.create(ssar);
}
@AfterEach
public void tearDown() { // 끝나고 나서 마무리 함수
// 테스트 후 정리할 코드
System.out.println("tearDown");
}
@Test
public void join_username_uk_fail_test() throws Exception { // 이 메서드를 호출한 주체에게 예외 위임 -> 지금은 jvm 이다
// given -> 가짜 데이터
UserRequest.JoinDTO reqDTO = new UserRequest.JoinDTO();
reqDTO.setEmail("ssar@nate.com");
reqDTO.setPassword("1234");
reqDTO.setUsername("ssar");
String requestBody = om.writeValueAsString(reqDTO);
// System.out.println(requestBody); // {"username":"haha","password":"1234","email":"haha@nate.com"}
// when -> 테스트 실행
ResultActions actions = mvc.perform( // 주소가 틀리면 터지고, json 아닌거 넣으면 터지고, 타입이 달라도 터지고. 따라서 미리 터진다고 알려줌
MockMvcRequestBuilders
.post("/join")
.content(requestBody)
.contentType(MediaType.APPLICATION_JSON)
);
// eye -> 결과 눈으로 검증
String responseBody = actions.andReturn().getResponse().getContentAsString();
//System.out.println(responseBody); // {"status":200,"msg":"성공","body":{"id":4,"username":"haha","email":"haha@nate.com","createdAt":"2025-05-13 11:45:23.604577"}}
// then -> 결과를 코드로 검증 // json의 최상위 객체를 $ 표기한다
actions.andExpect(MockMvcResultMatchers.jsonPath("$.status").value(400));
actions.andExpect(MockMvcResultMatchers.jsonPath("$.msg").value("중복된 유저네임이 존재합니다"));
actions.andExpect(MockMvcResultMatchers.jsonPath("$.body").value(Matchers.nullValue()));
actions.andDo(MockMvcResultHandlers.print()).andDo(document);
}
@Test
public void join_test() throws Exception { // 이 메서드를 호출한 주체에게 예외 위임 -> 지금은 jvm 이다
// given -> 가짜 데이터
UserRequest.JoinDTO reqDTO = new UserRequest.JoinDTO();
reqDTO.setEmail("haha@nate.com");
reqDTO.setPassword("1234");
reqDTO.setUsername("haha");
String requestBody = om.writeValueAsString(reqDTO);
// System.out.println(requestBody); // {"username":"haha","password":"1234","email":"haha@nate.com"}
// when -> 테스트 실행
ResultActions actions = mvc.perform( // 주소가 틀리면 터지고, json 아닌거 넣으면 터지고, 타입이 달라도 터지고. 따라서 미리 터진다고 알려줌
MockMvcRequestBuilders
.post("/join")
.content(requestBody)
.contentType(MediaType.APPLICATION_JSON)
);
// eye -> 결과 눈으로 검증
String responseBody = actions.andReturn().getResponse().getContentAsString();
//System.out.println(responseBody); // {"status":200,"msg":"성공","body":{"id":4,"username":"haha","email":"haha@nate.com","createdAt":"2025-05-13 11:45:23.604577"}}
// then -> 결과를 코드로 검증 // json의 최상위 객체를 $ 표기한다
actions.andExpect(MockMvcResultMatchers.jsonPath("$.status").value(200));
actions.andExpect(MockMvcResultMatchers.jsonPath("$.msg").value("성공"));
actions.andExpect(MockMvcResultMatchers.jsonPath("$.body.id").value(4));
actions.andExpect(MockMvcResultMatchers.jsonPath("$.body.username").value("haha"));
actions.andExpect(MockMvcResultMatchers.jsonPath("$.body.email").value("haha@nate.com"));
actions.andDo(MockMvcResultHandlers.print()).andDo(document);
}
@Test
public void login_test() throws Exception {
// given
UserRequest.LoginDTO reqDTO = new UserRequest.LoginDTO();
reqDTO.setUsername("ssar");
reqDTO.setPassword("1234");
String requestBody = om.writeValueAsString(reqDTO);
// System.out.println(requestBody);
// when
ResultActions actions = mvc.perform(
MockMvcRequestBuilders
.post("/login")
.content(requestBody)
.contentType(MediaType.APPLICATION_JSON)
);
// eye
String responseBody = actions.andReturn().getResponse().getContentAsString();
System.out.println(responseBody);
// then (jwt 길이만 검증) -> 길이 변환 가능. 패턴만 확인
actions.andExpect(MockMvcResultMatchers.jsonPath("$.status").value(200));
actions.andExpect(MockMvcResultMatchers.jsonPath("$.msg").value("성공"));
actions.andExpect(MockMvcResultMatchers.jsonPath("$.body.accessToken",
matchesPattern("^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+$")));
actions.andDo(MockMvcResultHandlers.print()).andDo(document);
}
@Test
public void update_test() throws Exception {
// given
UserRequest.UpdateDTO reqDTO = new UserRequest.UpdateDTO();
reqDTO.setEmail("ssar@gmail.com");
reqDTO.setPassword("1234");
String requestBody = om.writeValueAsString(reqDTO);
// System.out.println(requestBody);
// when
ResultActions actions = mvc.perform(
MockMvcRequestBuilders
.put("/s/api/user")
.content(requestBody)
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer " + accessToken)
);
System.out.println("AccessToken : " + accessToken);
// eye
String responseBody = actions.andReturn().getResponse().getContentAsString();
System.out.println(responseBody);
// then
actions.andExpect(MockMvcResultMatchers.jsonPath("$.status").value(200));
actions.andExpect(MockMvcResultMatchers.jsonPath("$.msg").value("성공"));
actions.andExpect(MockMvcResultMatchers.jsonPath("$.body.id").value(1));
actions.andExpect(MockMvcResultMatchers.jsonPath("$.body.username").value("ssar"));
actions.andExpect(MockMvcResultMatchers.jsonPath("$.body.email").value("ssar@gmail.com"));
actions.andExpect(MockMvcResultMatchers.jsonPath("$.body.createdAt",
matchesPattern("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}\\.\\d+")));
actions.andDo(MockMvcResultHandlers.print()).andDo(document);
}
@Test
public void check_username_available_test() throws Exception {
// given
String username = "ssar";
// when
ResultActions actions = mvc.perform(
MockMvcRequestBuilders
.get("/api/check-username-available/{username}", username)
);
// eye
String responseBody = actions.andReturn().getResponse().getContentAsString();
System.out.println(responseBody);
// then
actions.andExpect(MockMvcResultMatchers.jsonPath("$.status").value(200));
actions.andExpect(MockMvcResultMatchers.jsonPath("$.msg").value("성공"));
actions.andExpect(MockMvcResultMatchers.jsonPath("$.body.available").value(false));
actions.andDo(MockMvcResultHandlers.print()).andDo(document);
}
}
4. 컨트롤러들에 mvc 부모 옮기고 옮겨졌으니까 삭제해야 하는데 선생님 깃 복붙 한다고 삭제했던 거 다시 되돌아 옴 (한번 더 확인하기)
@Transactional
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)

5. 버그 : 빌드 한번 더 해야지 resource 폴더 안에 api.html이 생성됨


결과




Share article