@Pointcut("execution(* com.prac.music.domain.board.controller.*.*(..))")
private void board() {}
@Pointcut("execution(* com.prac.music.domain.comment.controller.*.*(..))")
private void comment() {}
@Pointcut("execution(* com.prac.music.domain.like.controller.*.*(..))")
private void like() {}
@Pointcut("execution(* com.prac.music.domain.mail.controller.*.*(..))")
private void mail() {}
@Pointcut("execution(* com.prac.music.domain.user.controller.*.*(..))")
private void user() {}
@Around("board() || comment() || like() || mail() || user()" )
public Object execute(ProceedingJoinPoint joinPoint) throws Throwable {
log.info(joinPoint.getSignature().toShortString() + " start");
try {
return joinPoint.proceed();
} finally {
log.info(joinPoint.getSignature().toShortString() + " end");
}
}
@Test
를 사용해서 DTO 와 Entity Test 를 추가합니다.@Test
@DisplayName("User Entity Test")
void test1() throws IOException {
// given
SignupRequestDto requestDto = new SignupRequestDto(
"testId1",
"testPassword1!",
"testName",
"test@email.com",
"test Introduce"
);
MultipartFile file = null;
// when
User user = userService.createUser(requestDto, file);
// then
assertEquals(requestDto.getUserId(), user.getUserId());
assertTrue(passwordEncoder.matches(requestDto.getPassword(), user.getPassword()));
assertEquals(requestDto.getName(), user.getName());
assertEquals(requestDto.getEmail(), user.getEmail());
assertEquals(requestDto.getIntro(), user.getIntro());
}
given 에 입력값, when에 생성 메서드(Post api)를 동작시켜 비교시켜 테스트
@WebMvcTest
를 사용하여 Controller Test 를 추가합니다.
🛠️ 오류해결
- ✨ JpaAuditing 관련 어노테이션 부착 후 해결
@WebMvcTest(
controllers = UserController.class,
excludeFilters = {
@ComponentScan.Filter(
type = FilterType.ASSIGNABLE_TYPE,
classes = SecurityConfiguration.class
)
}
)
@MockBean(JpaMetamodelMappingContext.class)
class UserControllerTest {
private MockMvc mvc;
private Principal mockPrincipal;
@Autowired
private WebApplicationContext context;
@Autowired
private ObjectMapper objectMapper;
private PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
@MockBean
private UserService userService;
private JwtService jwtService = new JwtService();
@BeforeEach
public void setup() {
mvc = MockMvcBuilders.webAppContextSetup(context)
.apply(springSecurity(new MockSpringSecurityFilter()))
.build();
}
@Test
@DisplayName("Signup Request")
void test1() throws Exception {
//given
SignupRequestDto requestDto = SignupRequestDto.builder()
.userId("testId1")
.password("testPassword1!")
.name("testName")
.email("test@email.com")
.intro("test Introduce")
.build();
MockMultipartFile file = new MockMultipartFile(
"file",
"profileImage.png",
"multipart/form-data",
"some image content".getBytes()
);
MockMultipartFile user = new MockMultipartFile(
"user",
"",
"application/json",
objectMapper.writeValueAsBytes(requestDto)
);
// when - then
mvc.perform(multipart("/api/users/signup")
.file(user)
.file(file))
.andExpect(status().isOk())
.andDo(print());
}
@Test
@DisplayName("Login Request")
public void test2() throws Exception {
//given
LoginRequestDto requestDto = LoginRequestDto.builder()
.userId("testId1")
.password("testPassword1!")
.build();
String jsonRequest = objectMapper.writeValueAsString(requestDto);
//when - then
mvc.perform(post("/api/users/login")
.contentType("application/json")
.content(jsonRequest))
.andExpect(status().isOk())
.andDo(print());
}
@Test
@DisplayName("Logout Request")
public void test3() throws Exception {
// given
User user = User.builder()
.userId("testId1")
.build();
UserDetailsImpl userDetails = new UserDetailsImpl(user);
mockPrincipal = new UsernamePasswordAuthenticationToken(userDetails, "");
// when
userService.logoutUser(userDetails.getUser());
// then
mvc.perform(put("/api/users/logout")
.principal(mockPrincipal))
.andExpect(status().isOk())
.andDo(print());
}
@Test
@DisplayName("Signout Request")
public void test4() throws Exception {
// given
User user = User.builder()
.id(1L)
.userId("testId1")
.password("testPassword1!")
.name("testName")
.email("test@email.com")
.intro("test Introduce")
.status(UserStatusEnum.NORMAL)
.refreshToken("fidsbafilubasdjiklfboia")
.profileImage(null)
.build();
SignoutRequestDto requestDto = SignoutRequestDto.builder()
.password("testPassword1!")
.build();
UserDetailsImpl userDetails = new UserDetailsImpl(user);
mockPrincipal = new UsernamePasswordAuthenticationToken(userDetails, "");
// when
// then
mvc.perform(put("/api/users/signout")
.principal(mockPrincipal)
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(requestDto)))
.andExpect(status().isOk())
.andDo(print());
}
}
JpaAuditing 관련 오류 외에도 기존 프로젝트에서 SignOut api 가 실행이 안되는 500코드 오류 발생
- 기존 requestDto의 필드가 하나 밖에 없어서 생기는 오류였음
->@Jacksonized
어노테이션으로 해결
@ExtendWith
를 사용하여 Service Test 를 추가합니다.package com.prac.music.service;
import com.prac.music.domain.board.dto.BoardRequestDto;
import com.prac.music.domain.board.dto.BoardResponseDto;
import com.prac.music.domain.board.service.BoardService;
import com.prac.music.domain.user.entity.User;
import com.prac.music.domain.user.entity.UserStatusEnum;
import com.prac.music.domain.user.service.JwtService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.List;
import static org.hibernate.validator.internal.util.Contracts.assertNotNull;
@ExtendWith(MockitoExtension.class) // @Mock 사용을 위해 설정합니다.
public class BoardServiceTest {
@Mock
JwtService jwtService;
@InjectMocks
BoardService boardService;
User user;
@BeforeEach
public void setUp() {
user = User.builder()
.id(1L)
.userId("testId1")
.password("testPassword1!")
.name("testName")
.email("test@email.com")
.intro("test Introduce")
.status(UserStatusEnum.NORMAL)
.refreshToken(jwtService.createRefreshToken("testId1"))
.profileImage(null)
.build();
}
@Test
@DisplayName("createBoard Success")
void test1() throws IOException {
//given
BoardRequestDto requestDto = BoardRequestDto.builder()
.title("test title")
.contents("test contents")
.build();
List<MultipartFile> files = List.of();
//when
BoardResponseDto createdBoard = boardService.createBoard(requestDto, user, files);
//then
assertNotNull(createdBoard);
}
}
@Setup
어노테이션으로 기존재해야할 엔티티를 미리 작성하고 테스트를 진행하는 방식으로 작성했다.
그런데 작성하고 보니 기존 Entity Test에서 진행했던 방식과 동일한 것으로 여겨져서 Entity Test를 더 단순하게 생각했어야 하는 구나 하고 생각했다.