Sparta 내일배움캠프 Java 5기/[최종 프로젝트] 커뮤니티 서비스 Team Project ✓
(24.07.26) 코드 리뷰 기능(게시글, 댓글, 좋아요) 테스트 코드 작성
통합 테스트 코드 작성
Controller 테스트 코드
- @WebMvcTest 테스트 코드 진행
MockSpringSecurityFilter 사용
public class MockSpringSecurityFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) {}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
SecurityContextHolder.getContext()
.setAuthentication((Authentication) ((HttpServletRequest) req).getUserPrincipal());
chain.doFilter(req, res);
}
@Override
public void destroy() {
SecurityContextHolder.clearContext();
}
}
- 인증에 대한 UserDetails을 가져와야하기 때문에 기능을 사용하기 위해서 인증인가 Filter를 거치고 있음 -> Filter를 제외시켜주는 작업을 해줄 수 있도록 MockSpringSecurityFilter를 만들어서 테스트 코드에서 사용
WebMvcTest
@WebMvcTest(
controllers = {CodeReviewsController.class},
excludeFilters = {
@ComponentScan.Filter(
type = FilterType.ASSIGNABLE_TYPE,
classes = WebSecurityConfig.class
)
}
)
class CodeReviewsControllerTest {
private MockMvc mockMvc;
private Principal mockPrincipal;
@Autowired
private WebApplicationContext context;
@MockBean
private CodeReviewsService codeReviewsService;
...
@BeforeEach
public void setUp() {
mockMvc = MockMvcBuilders.webAppContextSetup(context)
.apply(
springSecurity(new MockSpringSecurityFilter()))
.build();
}
private void mockUserSetup() {
Users user = Users.builder()
.name("testuser")
.email("test@example.com")
.password("Test123!")
.role(RoleEnum.USER)
.build();
UserDetailsImpl testUserDetails = new UserDetailsImpl(user);
mockPrincipal = new UsernamePasswordAuthenticationToken(testUserDetails, "",
testUserDetails.getAuthorities());
}
...
- 앞서만든MockSpringSecurityFilter 를 사용할 수 있도록 매 테스트에 BeforeEach로 설정
- 임의로 만든 user -> 이 정보를 담은 testUserDetails과 principal을 사용할 때, 이 UserDetail 정보를 쓸 수 있도록 mockPrincipal 지정
// when
MockHttpServletRequestBuilder request = MockMvcRequestBuilders.post("/api/codereviews")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(codeReviewsRequestDto))
.principal(mockPrincipal);
- MockHttpServletRequestBuilder 로 요청을 임의로 만들때 .principal(mockPrincipal) 로 설정 가능
일련의 모든 Controller는 해당 작업을 통해 인증을 거친 후 테스트 코드를 작성
Service 테스트 코드
spring:
datasource:
url: jdbc:h2:mem:PublicClassDev
driver-class-name: org.h2.Driver
username: sa
password:
h2:
console:
enabled: true
jpa:
hibernate:
ddl-auto: update
show-sql: true
- in memory 를 사용하기 위해서 application-test.yml을 따로 만들어서 활용 가능
@SpringBootTest
@ActiveProfiles("test")
public class CodeReviewsServiceTest {
...
- 통합테스트를 진행을 해서 저장된 데이터에 대한 비지니스 로직 테스트 코드를 위해서 ActiveProfile을 통해서 인메모리에 해당 작업을 할 수 있도록 세팅
- 테스트를 위한 DB에 save 작업이 존재
Repository 테스트 코드
@DataJpaTest
@ActiveProfiles("test")
public class CodeReviewsRepositoryTest {
...
- JpaRepository에서 JPQL을 활용해서 코드가 작성되었기 때문에 JPA 테스트하기 위해 DataJpaTest 테스트 진행
- EntityManager, JpaRepositories 등 자동으로 설정
- SpringBootTest와 마찬가지로 Transactional 사용
'Sparta 내일배움캠프 Java 5기 > [최종 프로젝트] 커뮤니티 서비스 Team Project ✓' 카테고리의 다른 글
(24.08.19) 최종 프로젝트 점검 및 정리 (0) | 2024.08.19 |
---|---|
(24.07.26) CI/CD 파이프 라인 구상 및 테스트 코드 점검 (0) | 2024.07.26 |
(24.07.24) 코드 리뷰 게시글 조회 & 카테고리 검색 기능 구현 (1) | 2024.07.24 |
(24.07.23) 코드 리뷰 게시글 수정/삭제 기능 구현 + 코드 리뷰 댓글 생성/수정/삭제 기능 구현 + 댓글 좋아요 추가/삭제 기능 구현 (2) | 2024.07.24 |
(24.07.22) 코드 리뷰 게시글 생성 기능 구현 (1) | 2024.07.23 |