Project/Boilerplate

Mock 테스트 중 엔티티 id 및 SecurityContextHolder 설정

조용우 2025. 4. 2. 19:09
@BeforeEach
void setUp() {
    testUser = User.builder()
    	.id(1L) // 오류
        .email("test@example.com")
        .build();

 

User 엔티티는 id를 세팅할 수 있는 빌더가 없음. 그렇다고 AllArgsConstructor를 넣는 것은 위험함.

따라서, 리플렉션을 이용해서 필드 값을 강제 설정.

 

public class TestReflectionUtil {

    public static void setId(Object target, Long id) {
        try {
            Field field = target.getClass().getDeclaredField("id");
            field.setAccessible(true);
            field.set(target, id);
        } catch (Exception e) {
            throw new RuntimeException("ID 설정 실패", e);
        }
    }
}
@BeforeEach
void setUp() {
    testUser = User.builder()
        .email("test@example.com")
        .build();
    setId(testUser, 1L);

 

 


 

@PostMapping
public ResponseEntity<CommentResponse> createComment(
    @PathVariable Long postId,
    @Valid @RequestBody CommentRequest request
) {
    return ResponseEntity.ok(
        commentService.create(
            SecurityUtil.getCurrentUserId(),
            postId,
            request.getContent(),
            request.getParentCommentId()
        )
    );
}

컨트롤러는 SecurityUtil.getCurrentuserId()를 호출하여 서비스로 보냄

public static Long getCurrentUserId() {
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    if (authentication == null || !authentication.isAuthenticated()) {
        throw new AuthenticationFailedException();
    }

    CustomUserDetails userDetails = (CustomUserDetails) authentication.getPrincipal();
    return userDetails.getId();
}

 

근데, 당연히도 로그인이 되어있지 않기 때문에 null을 반환함.

@BeforeEach
void setUp() {
    testUser = User.builder()
        .email("test@example.com")
        .username("test")
        .name("test")
        .role(Role.USER)
        .build();
    setId(testUser, 1L);

    PostAndCommentUserResponse user = PostAndCommentUserResponse.from(testUser);
    setUpAuthentication();
    testCommentResponse = CommentResponse.builder()
        .id(1L)
        .content("Test Comment")
        .user(user)
        .parentCommentId(null)
        .build();
}

void setUpAuthentication() {
    CustomUserDetails userDetails = new CustomUserDetails(testUser);
    UsernamePasswordAuthenticationToken authentication =
        new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
    SecurityContextHolder.getContext().setAuthentication(authentication);
}

@AfterEach
void clearSecurityContext() {
    SecurityContextHolder.clearContext();
}

testUser를 userDetails에 주입하는 과정 추가