컨트롤러단에서 @AuthenticationPrincipal을 이용해 id값을 가져와 쓰고 있었다.
테스트 코드를 작성하는데 id값을 어떻게 가져와야 할 지 몰랐다. 그래서 @WithCustomMockUser 어노테이션을 만들어 사용하였다.
package com.swyp.libri.domain.annotation;
import org.springframework.security.test.context.support.WithSecurityContext;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
@WithSecurityContext(factory = WithCustomMockUserSecurityContextFactory.class)
public @interface WithCustomMockUser {
String email() default "test@example.com";
String role() default "ROLE_USER";
long id() default 1L;
}
package com.swyp.libri.domain.annotation;
import com.swyp.libri.domain.model.Member;
import com.swyp.libri.global.oauth2.CustomUserPrincipal;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.test.context.support.WithSecurityContextFactory;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.test.util.ReflectionTestUtils;
import java.util.Collections;
public class WithCustomMockUserSecurityContextFactory implements WithSecurityContextFactory<WithCustomMockUser> {
@Override
public SecurityContext createSecurityContext(WithCustomMockUser customUser) {
SecurityContext context = SecurityContextHolder.createEmptyContext();
Member member = new Member(customUser.email(), "provider", "id");
ReflectionTestUtils.setField(member, "id", customUser.id());
CustomUserPrincipal principal = new CustomUserPrincipal(
member,
Collections.emptyMap(),
Collections.singletonList(new SimpleGrantedAuthority(customUser.role()))
);
Authentication authentication = new TestingAuthenticationToken(principal, null);
authentication.setAuthenticated(true);
context.setAuthentication(authentication);
return context;
}
}
테스트 코드
package com.swyp.libri.domain.controller;
import com.swyp.libri.domain.annotation.WithCustomMockUser;
import com.swyp.libri.domain.auth.dto.UniqueIdRequest;
import com.swyp.libri.domain.model.Member;
import com.swyp.libri.domain.repository.MemberRepository;
import com.swyp.libri.domain.service.MemberService;
import com.swyp.libri.global.oauth2.CustomUserPrincipal;
import com.swyp.libri.global.util.ApiDocumentation;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.MediaType;
import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper;
import java.security.Principal;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@WithCustomMockUser
@AutoConfigureRestDocs
@WebMvcTest(MemberController.class)
class MemberControllerTest {
@Autowired
private MockMvc mockMvc;
@MockitoBean
private MemberService memberService;
private static final String URL = "/member";
private static final String TAG = "MEMBER";
@Test
void createUniqueId() throws Exception {
Long memberId = 1L;
String uniqueId = "unique123";
doNothing().when(memberService).createUniqueId(memberId, uniqueId);
ResultActions actions = mockMvc.perform(RestDocumentationRequestBuilders.post(URL + "/create/unique-id")
.content(new ObjectMapper().writeValueAsString(new UniqueIdRequest(uniqueId)))
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.with(csrf().asHeader()));
actions.andExpect(status().isOk())
.andDo(ApiDocumentation.builder()
.tag(TAG)
.description("아이디 생성 API")
.requestFields(
fieldWithPath("uniqueId").description("생성할 유니크 ID")
)
.build())
.andDo(print());
verify(memberService).createUniqueId(memberId, uniqueId);
}
}
@WithCustomMockUser로 컨트롤러단에서 테스트 코드를 만들 수 있었다.
'개발이 좋아서 > Troubleshooting이 좋아서' 카테고리의 다른 글
cors 에러 문제 - trim을 안했다.. (0) | 2025.03.03 |
---|---|
빈 등록 안하고 싶을 때 - @Autowired(required = false) (0) | 2025.02.27 |
There were failing tests. See the report at: file:///C:/repository/ 프로젝트/build/reports/tests/test/index.html (0) | 2025.02.17 |