Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
Tags
- 리액트
- 노마드코더
- Stack
- dfs
- 알고리즘
- ReactJS로 영화 웹 서비스 만들기
- 프로그래머스
- SoftwareExpertAcademy
- Java
- 완전탐색
- 경제공부
- 백준
- 재귀
- JPA
- Algorithm
- React.js
- 달빛클럽 1기
- programmers
- 카카오블라인드코딩테스트
- HashMap
- Array
- BOJ
- React
- 달빛캠퍼스
- 노마드코더 강의
- 달빛클럽
- 자바
- SWEA
- 인플레이션에서 살아남기
- 달빛클럽1기
Archives
- Today
- Total
th42500의 TIL
[JUnit] @Nested란? 본문
프로젝트 발표 시간에 다른 교육생들의 발표를 듣다가 @Nested라는 Annotation을 처음 알게되어 직접 적용해보고 블로그 글을 작성하게 되었다.
@Nested Test 란?
- 테스트 작성자에게 여러 테스트 그룹 간의 관계를 표현할 수 있도록 해주는 Annotation
- import org.junit.jupiter.api에서 제공하는 기능
- 외부 테스트의 설정 코드가 내부 테스트가 실행되기 전에 실행되므로 모든 테스트를 독립적으로 실행할 수 있음
⚠ @BeforeAll 또는 @AfterAll 를 제외한 중첩 클래스 (내부 클래스)만 @Nested 테스트 클래스로 사용 가능
👉 Java16 이전 버전에서는 내부 클래스에서 static을 허용하지 않기 때문
👉 @TestInstance(Lifecycle.PER_CLASS) 를 이용하여 @Nested 테스트 클래스에 주석을 달면 해결 가능
@Nested 적용
- 관심사가 비슷한 메소드들을 @Nested 로 묶음
- 전체적인 코드의 양은 늘어나지만 계층적인 구조로 이루어져 있어 가독성이 높아짐
- 클래스로 구분되어 있어 success 또는 fail 등의 각 기능별 내부 테스트 코드 클래스명이 같아도 문제가 없음
기존 코드 - @Nested 적용 전
package com.likelion.healing.controller;
// import 생략
@WebMvcTest(PostController.class)
@WithMockUser
class PostControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
PostService postService;
@Autowired
ObjectMapper objectMapper;
@Test
@DisplayName("포스트 작성 성공")
void successfulCreatePost() throws Exception {
PostReq req = PostReq.builder()
.title("title1")
.body("body1")
.build();
given(postService.createPost(any(PostReq.class), "Bearer " + any(String.class))).willReturn(new PostRes("포스트 등록 완료", 1));
mockMvc.perform(post("/api/v1/posts")
.with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsBytes(req)))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.resultCode").value("SUCCESS"))
.andExpect(jsonPath("$.result.message").value("포스트 등록 완료"))
.andExpect(jsonPath("$.result.postId").value(1));
}
@Test
@WithAnonymousUser
@DisplayName("포스트 작성 실패 - JWT를 Bearer Token으로 보내지 않은 경우")
void notStartsWithBearer() throws Exception {
PostReq req = PostReq.builder()
.title("title1")
.body("body1")
.build();
given(postService.createPost(any(PostReq.class), any(String.class))).willThrow(new HealingSnsAppException(ErrorCode.INVALID_PERMISSION, "사용자가 권한이 없습니다."));
mockMvc.perform(post("/api/v1/posts")
.with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsBytes(req)))
.andDo(print())
.andExpect(status().isUnauthorized());
}
@Test
@WithAnonymousUser
@DisplayName("포스트 작성 실패 - JWT가 유효하지 않은 경우")
void expiredToken() throws Exception {
PostReq req = PostReq.builder()
.title("title1")
.body("body1")
.build();
given(postService.createPost(any(PostReq.class), "Bearer " + any(String.class))).willThrow(new HealingSnsAppException(ErrorCode.INVALID_PERMISSION, "사용자가 권한이 없습니다."));
mockMvc.perform(post("/api/v1/posts")
.with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsBytes(req)))
.andDo(print())
.andExpect(status().isUnauthorized());
}
@Test
@DisplayName("포스트 전체 목록 조회 - 생성일자 내림차순")
void getPostList() throws Exception {
List<PostViewRes> postList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
LocalDateTime now = LocalDateTime.now().plusMinutes(i);
postList.add(new PostViewRes(i, "title"+i, "body"+i, "test", now, now));
}
Page<PostViewRes> postViewResPage = new PageImpl<>(postList);
postViewResPage.stream().sorted(Comparator.comparing(PostViewRes::getCreatedAt).reversed());
given(postService.getPostList(any(Pageable.class))).willReturn(postViewResPage);
mockMvc.perform(get("/api/v1/posts")
.param("page", "0")
.param("size", "10")
.param("sort", "createdAt,desc"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.resultCode").value("SUCCESS"));
}
@Test
@DisplayName("포스트 단건 조회 성공")
void successfulGetPostById() throws Exception {
Integer postId = 1;
PostViewRes post = PostViewRes.builder()
.id(1)
.title("title1")
.body("body1")
.userName("Soyeong")
.createdAt(LocalDateTime.now())
.lastModifiedAt(LocalDateTime.now())
.build();
given(postService.getPostById(any(Integer.class))).willReturn(post);
mockMvc.perform(get(String.format("/api/v1/posts/%d", postId))
.with(csrf()))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.resultCode").value("SUCCESS"))
.andExpect(jsonPath("$.result.id").value(1))
.andExpect(jsonPath("$.result.title").value("title1"))
.andExpect(jsonPath("$.result.body").value("body1"))
.andExpect(jsonPath("$.result.userName").value("Soyeong"))
.andExpect(jsonPath("$.result.createdAt").exists())
.andExpect(jsonPath("$.result.lastModifiedAt").exists());
}
@Test
@WithAnonymousUser
@DisplayName("포스트 수정 실패 - 인증 실패")
void update_authenticationFailed() throws Exception {
PostReq req = PostReq.builder()
.title("test title")
.body("test body")
.build();
UserEntity user = UserEntity.builder()
.userName("Soyeong")
.password("12345")
.build();
Integer postId = 1;
given(postService.updatePostById(any(Integer.class), any(PostReq.class), any(String.class), any(String.class))).willThrow(new HealingSnsAppException(ErrorCode.USERNAME_NOT_FOUND, String.format("%s은(는) 없는 회원입니다.", user.getUsername())));
mockMvc.perform(put(String.format("/api/v1/posts/%d", postId))
.with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsBytes(req)))
.andDo(print())
.andExpect(status().isUnauthorized());
}
@Test
@DisplayName("포스트 수정 실패 - 작성자 불일치")
void update_mismatchedAuthorAndUser() throws Exception {
PostReq req = PostReq.builder()
.title("test title")
.body("test body")
.build();
Integer postId = 1;
given(postService.updatePostById(any(Integer.class), any(PostReq.class), any(String.class), any(String.class))).willThrow(new HealingSnsAppException(ErrorCode.INVALID_PERMISSION, "사용자가 권한이 없습니다."));
mockMvc.perform(put(String.format("/api/v1/posts/%d", postId))
.with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsBytes(req)))
.andDo(print())
.andExpect(status().isUnauthorized())
.andExpect(jsonPath("$.resultCode").value("ERROR"))
.andExpect(jsonPath("$.result.errorCode").value("INVALID_PERMISSION"))
.andExpect(jsonPath("$.result.message").value("사용자가 권한이 없습니다."));
}
@Test
@DisplayName("포스트 수정 실패 - 데이터베이스 에러")
void update_notFoundDatabase() throws Exception {
PostReq req = PostReq.builder()
.title("test title")
.body("test body")
.build();
Integer postId = 1;
given(postService.updatePostById(any(Integer.class), any(PostReq.class), any(String.class), any(String.class))).willThrow(new HealingSnsAppException(ErrorCode.DATABASE_ERROR, "DB에러"));
mockMvc.perform(put(String.format("/api/v1/posts/%d", postId))
.with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsBytes(req)))
.andDo(print())
.andExpect(status().isInternalServerError())
.andExpect(jsonPath("$.resultCode").value("ERROR"))
.andExpect(jsonPath("$.result.errorCode").value("DATABASE_ERROR"))
.andExpect(jsonPath("$.result.message").value("DB에러"));
}
@Test
@DisplayName("포스트 수정 성공")
void successfulEdit() throws Exception {
PostReq req = PostReq.builder()
.title("test title")
.body("test body")
.build();
Integer postId = 1;
given(postService.updatePostById(any(Integer.class), any(PostReq.class), any(String.class), any(String.class))).willReturn(new PostRes("포스트 수정 완료", postId));
mockMvc.perform(put(String.format("/api/v1/posts/%d", postId))
.with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsBytes(req)))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.resultCode").value("SUCCESS"))
.andExpect(jsonPath("$.result.message").value("포스트 수정 완료"))
.andExpect(jsonPath("$.result.postId").value(postId));
}
@Test
@DisplayName("포스트 삭제 성공")
void successfulDelete() throws Exception {
Integer postId = 1;
given(postService.deletePostById(any(Integer.class), any(String.class), any(String.class))).willReturn(new PostRes("포스트 삭제 완료", postId));
mockMvc.perform(delete(String.format("/api/v1/posts/%d", postId))
.with(csrf()))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.resultCode").value("SUCCESS"))
.andExpect(jsonPath("$.result.message").value("포스트 삭제 완료"))
.andExpect(jsonPath("$.result.postId").value(postId));
}
@Test
@WithAnonymousUser
@DisplayName("포스트 삭제 실패 - 인증 실패")
void delete_authenticationFailed() throws Exception {
UserEntity user = UserEntity.builder()
.userName("Soyeong")
.password("12345")
.build();
Integer postId = 1;
given(postService.deletePostById(any(Integer.class), any(String.class), any(String.class))).willThrow(new HealingSnsAppException(ErrorCode.USERNAME_NOT_FOUND, String.format("%s은(는) 없는 회원입니다.", user.getUsername())));
mockMvc.perform(delete(String.format("/api/v1/posts/%d", postId))
.with(csrf()))
.andDo(print())
.andExpect(status().isUnauthorized());
}
@Test
@DisplayName("포스트 삭제 실패 - 작성자 불일치")
void delete_mismatchedAuthorAndUser() throws Exception {
Integer postId = 1;
given(postService.deletePostById(any(Integer.class), any(String.class), any(String.class))).willThrow(new HealingSnsAppException(ErrorCode.INVALID_PERMISSION, "사용자가 권한이 없습니다."));
mockMvc.perform(delete(String.format("/api/v1/posts/%d", postId))
.with(csrf()))
.andDo(print())
.andExpect(status().isUnauthorized())
.andExpect(jsonPath("$.resultCode").value("ERROR"))
.andExpect(jsonPath("$.result.errorCode").value("INVALID_PERMISSION"))
.andExpect(jsonPath("$.result.message").value("사용자가 권한이 없습니다."));
}
@Test
@DisplayName("포스트 삭제 실패 - 데이터베이스 에러")
void delete_notFoundDatabase() throws Exception {
Integer postId = 1;
given(postService.deletePostById(any(Integer.class), any(String.class), any(String.class))).willThrow(new HealingSnsAppException(ErrorCode.DATABASE_ERROR, "DB에러"));
mockMvc.perform(delete(String.format("/api/v1/posts/%d", postId))
.with(csrf()))
.andDo(print())
.andExpect(status().isInternalServerError())
.andExpect(jsonPath("$.resultCode").value("ERROR"))
.andExpect(jsonPath("$.result.errorCode").value("DATABASE_ERROR"))
.andExpect(jsonPath("$.result.message").value("DB에러"));
}
@Test
@DisplayName("마이피드 조회 성공")
void successfulGetMyFeed() throws Exception {
given(postService.getMyFeed(any(Pageable.class), any(String.class))).willReturn(Page.empty());
mockMvc.perform(get("/api/v1/posts/my")
.param("page", "0")
.param("size", "10")
.param("sort", "createdAt,desc")
.param("userName", "user"))
.andDo(print())
.andExpect(status().isOk());
}
@Test
@WithAnonymousUser
@DisplayName("마이피드 조회 실패 - 로그인 하지 않은 경우")
void NotLogin() throws Exception {
given(postService.getMyFeed(any(Pageable.class), any(String.class))).willReturn(Page.empty());
mockMvc.perform(get("/api/v1/posts/my")
.param("page", "0")
.param("size", "10")
.param("sort", "createdAt,desc")
.param("userName", "user"))
.andDo(print())
.andExpect(status().isUnauthorized());
}
}
모든 테스트가 한번에 실행되었을 때 가독성이 좋지 않음
리팩토링 후 코드 - @Nested 적용 후
package com.likelion.healing.controller;
// import 생략
@WebMvcTest(PostController.class)
@WithMockUser
class PostControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
PostService postService;
@Autowired
ObjectMapper objectMapper;
@Nested
@DisplayName("포스트 작성 테스트")
class CreatePostTest{
@Test
@DisplayName("포스트 작성 성공")
void successCreatePost() throws Exception {
PostReq req = PostReq.builder()
.title("title1")
.body("body1")
.build();
given(postService.createPost(any(PostReq.class), "Bearer " + any(String.class))).willReturn(new PostRes("포스트 등록 완료", 1));
mockMvc.perform(post("/api/v1/posts")
.with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsBytes(req)))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.resultCode").value("SUCCESS"))
.andExpect(jsonPath("$.result.message").value("포스트 등록 완료"))
.andExpect(jsonPath("$.result.postId").value(1));
}
@Test
@WithAnonymousUser
@DisplayName("포스트 작성 실패 - JWT를 Bearer Token으로 보내지 않은 경우")
void notStartsWithBearer() throws Exception {
PostReq req = PostReq.builder()
.title("title1")
.body("body1")
.build();
given(postService.createPost(any(PostReq.class), any(String.class))).willThrow(new HealingSnsAppException(ErrorCode.INVALID_PERMISSION, "사용자가 권한이 없습니다."));
mockMvc.perform(post("/api/v1/posts")
.with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsBytes(req)))
.andDo(print())
.andExpect(status().isUnauthorized());
}
@Test
@WithAnonymousUser
@DisplayName("포스트 작성 실패 - JWT가 유효하지 않은 경우")
void expiredToken() throws Exception {
PostReq req = PostReq.builder()
.title("title1")
.body("body1")
.build();
given(postService.createPost(any(PostReq.class), "Bearer " + any(String.class))).willThrow(new HealingSnsAppException(ErrorCode.INVALID_PERMISSION, "사용자가 권한이 없습니다."));
mockMvc.perform(post("/api/v1/posts")
.with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsBytes(req)))
.andDo(print())
.andExpect(status().isUnauthorized());
}
}
@Test
@DisplayName("포스트 전체 목록 조회 - 생성일자 내림차순")
void getPostList() throws Exception {
List<PostViewRes> postList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
LocalDateTime now = LocalDateTime.now().plusMinutes(i);
postList.add(new PostViewRes(i, "title"+i, "body"+i, "test", now, now));
}
Page<PostViewRes> postViewResPage = new PageImpl<>(postList);
postViewResPage.stream().sorted(Comparator.comparing(PostViewRes::getCreatedAt).reversed());
given(postService.getPostList(any(Pageable.class))).willReturn(postViewResPage);
mockMvc.perform(get("/api/v1/posts")
.param("page", "0")
.param("size", "10")
.param("sort", "createdAt,desc"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.resultCode").value("SUCCESS"));
}
@Test
@DisplayName("포스트 단건 조회 성공")
void successGetPostById() throws Exception {
Integer postId = 1;
PostViewRes post = PostViewRes.builder()
.id(1)
.title("title1")
.body("body1")
.userName("Soyeong")
.createdAt(LocalDateTime.now())
.lastModifiedAt(LocalDateTime.now())
.build();
given(postService.getPostById(any(Integer.class))).willReturn(post);
mockMvc.perform(get(String.format("/api/v1/posts/%d", postId))
.with(csrf()))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.resultCode").value("SUCCESS"))
.andExpect(jsonPath("$.result.id").value(1))
.andExpect(jsonPath("$.result.title").value("title1"))
.andExpect(jsonPath("$.result.body").value("body1"))
.andExpect(jsonPath("$.result.userName").value("Soyeong"))
.andExpect(jsonPath("$.result.createdAt").exists())
.andExpect(jsonPath("$.result.lastModifiedAt").exists());
}
@Nested
@DisplayName("포스트 수정 테스트")
class UpdatePostTest {
@Test
@WithAnonymousUser
@DisplayName("포스트 수정 실패 - 인증 실패")
void authenticationFailed() throws Exception {
PostReq req = PostReq.builder()
.title("test title")
.body("test body")
.build();
UserEntity user = UserEntity.builder()
.userName("Soyeong")
.password("12345")
.build();
Integer postId = 1;
given(postService.updatePostById(any(Integer.class), any(PostReq.class), any(String.class), any(String.class))).willThrow(new HealingSnsAppException(ErrorCode.USERNAME_NOT_FOUND, String.format("%s은(는) 없는 회원입니다.", user.getUsername())));
mockMvc.perform(put(String.format("/api/v1/posts/%d", postId))
.with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsBytes(req)))
.andDo(print())
.andExpect(status().isUnauthorized());
}
@Test
@DisplayName("포스트 수정 실패 - 작성자 불일치")
void mismatchedAuthorAndUser() throws Exception {
PostReq req = PostReq.builder()
.title("test title")
.body("test body")
.build();
Integer postId = 1;
given(postService.updatePostById(any(Integer.class), any(PostReq.class), any(String.class), any(String.class))).willThrow(new HealingSnsAppException(ErrorCode.INVALID_PERMISSION, "사용자가 권한이 없습니다."));
mockMvc.perform(put(String.format("/api/v1/posts/%d", postId))
.with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsBytes(req)))
.andDo(print())
.andExpect(status().isUnauthorized())
.andExpect(jsonPath("$.resultCode").value("ERROR"))
.andExpect(jsonPath("$.result.errorCode").value("INVALID_PERMISSION"))
.andExpect(jsonPath("$.result.message").value("사용자가 권한이 없습니다."));
}
@Test
@DisplayName("포스트 수정 실패 - 데이터베이스 에러")
void notFoundDatabase() throws Exception {
PostReq req = PostReq.builder()
.title("test title")
.body("test body")
.build();
Integer postId = 1;
given(postService.updatePostById(any(Integer.class), any(PostReq.class), any(String.class), any(String.class))).willThrow(new HealingSnsAppException(ErrorCode.DATABASE_ERROR, "DB에러"));
mockMvc.perform(put(String.format("/api/v1/posts/%d", postId))
.with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsBytes(req)))
.andDo(print())
.andExpect(status().isInternalServerError())
.andExpect(jsonPath("$.resultCode").value("ERROR"))
.andExpect(jsonPath("$.result.errorCode").value("DATABASE_ERROR"))
.andExpect(jsonPath("$.result.message").value("DB에러"));
}
@Test
@DisplayName("포스트 수정 성공")
void successUpdatePost() throws Exception {
PostReq req = PostReq.builder()
.title("test title")
.body("test body")
.build();
Integer postId = 1;
given(postService.updatePostById(any(Integer.class), any(PostReq.class), any(String.class), any(String.class))).willReturn(new PostRes("포스트 수정 완료", postId));
mockMvc.perform(put(String.format("/api/v1/posts/%d", postId))
.with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsBytes(req)))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.resultCode").value("SUCCESS"))
.andExpect(jsonPath("$.result.message").value("포스트 수정 완료"))
.andExpect(jsonPath("$.result.postId").value(postId));
}
}
@Nested
@DisplayName("포스트 삭제 테스트")
class DeletePostTest {
@Test
@DisplayName("포스트 삭제 성공")
void successDeletePost() throws Exception {
Integer postId = 1;
given(postService.deletePostById(any(Integer.class), any(String.class), any(String.class))).willReturn(new PostRes("포스트 삭제 완료", postId));
mockMvc.perform(delete(String.format("/api/v1/posts/%d", postId))
.with(csrf()))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.resultCode").value("SUCCESS"))
.andExpect(jsonPath("$.result.message").value("포스트 삭제 완료"))
.andExpect(jsonPath("$.result.postId").value(postId));
}
@Test
@WithAnonymousUser
@DisplayName("포스트 삭제 실패 - 인증 실패")
void authenticationFailed() throws Exception {
UserEntity user = UserEntity.builder()
.userName("Soyeong")
.password("12345")
.build();
Integer postId = 1;
given(postService.deletePostById(any(Integer.class), any(String.class), any(String.class))).willThrow(new HealingSnsAppException(ErrorCode.USERNAME_NOT_FOUND, String.format("%s은(는) 없는 회원입니다.", user.getUsername())));
mockMvc.perform(delete(String.format("/api/v1/posts/%d", postId))
.with(csrf()))
.andDo(print())
.andExpect(status().isUnauthorized());
}
@Test
@DisplayName("포스트 삭제 실패 - 작성자 불일치")
void mismatchedAuthorAndUser() throws Exception {
Integer postId = 1;
given(postService.deletePostById(any(Integer.class), any(String.class), any(String.class))).willThrow(new HealingSnsAppException(ErrorCode.INVALID_PERMISSION, "사용자가 권한이 없습니다."));
mockMvc.perform(delete(String.format("/api/v1/posts/%d", postId))
.with(csrf()))
.andDo(print())
.andExpect(status().isUnauthorized())
.andExpect(jsonPath("$.resultCode").value("ERROR"))
.andExpect(jsonPath("$.result.errorCode").value("INVALID_PERMISSION"))
.andExpect(jsonPath("$.result.message").value("사용자가 권한이 없습니다."));
}
@Test
@DisplayName("포스트 삭제 실패 - 데이터베이스 에러")
void notFoundDatabase() throws Exception {
Integer postId = 1;
given(postService.deletePostById(any(Integer.class), any(String.class), any(String.class))).willThrow(new HealingSnsAppException(ErrorCode.DATABASE_ERROR, "DB에러"));
mockMvc.perform(delete(String.format("/api/v1/posts/%d", postId))
.with(csrf()))
.andDo(print())
.andExpect(status().isInternalServerError())
.andExpect(jsonPath("$.resultCode").value("ERROR"))
.andExpect(jsonPath("$.result.errorCode").value("DATABASE_ERROR"))
.andExpect(jsonPath("$.result.message").value("DB에러"));
}
}
@Nested
@DisplayName("마이피드 조회 테스트")
class GetMyFeed {
@Test
@DisplayName("마이피드 조회 성공")
void successGetMyFeed() throws Exception {
given(postService.getMyFeed(any(Pageable.class), any(String.class))).willReturn(Page.empty());
mockMvc.perform(get("/api/v1/posts/my")
.param("page", "0")
.param("size", "10")
.param("sort", "createdAt,desc")
.param("userName", "user"))
.andDo(print())
.andExpect(status().isOk());
}
@Test
@WithAnonymousUser
@DisplayName("마이피드 조회 실패 - 로그인 하지 않은 경우")
void NotLogin() throws Exception {
given(postService.getMyFeed(any(Pageable.class), any(String.class))).willReturn(Page.empty());
mockMvc.perform(get("/api/v1/posts/my")
.param("page", "0")
.param("size", "10")
.param("sort", "createdAt,desc")
.param("userName", "user"))
.andDo(print())
.andExpect(status().isUnauthorized());
}
}
}
이렇게 @Nested 를 활용하면 Test 코드는 길어지지만 결과가 계층구조로 나오기 때문에 훨씬 가독성 있게 테스트를 확인할 수 있다.
또한, @DisplayName("테스트이름")을 함께 작성하면 메서드명이 아닌 지정한 테스트명으로 테스트 결과를 더 알아보기 쉽다.
'Backend > JUnit & BDD' 카테고리의 다른 글
MockTest 시 null 값이 뜨는 이유 (0) | 2023.01.26 |
---|---|
Given-When-Then 패턴과 given()&when() (0) | 2023.01.03 |
[Test] MockTest 중 발생한 401 (Unauthorized) 에러 (0) | 2023.01.01 |
Comments