Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BE] 테스트 코드 리팩토링 #730

Open
wants to merge 12 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이거 버저닝 걷어내고 살렸으면 작업량이 줄어드셨을텐데... 고생 많으셨어요 😭

Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package harustudy.backend.acceptance;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 클래스에 안 쓰게 된 import문들 정리해줘야 할 것 같아요

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 반영하겠습니다!!


import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
Expand All @@ -27,9 +28,6 @@
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DisplayNameGeneration;
import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores;
import org.junit.jupiter.api.Test;
Expand All @@ -43,42 +41,31 @@
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.WebApplicationContext;

@SuppressWarnings("NonAsciiCharacters")
@DisplayNameGeneration(ReplaceUnderscores.class)
@ExtendWith(MockitoExtension.class)
@SpringBootTest
@AutoConfigureMockMvc
@Transactional
@Disabled("무중단 배포를 위한 API 버저닝으로 인한 임시 disabled")
class AcceptanceTest {

@MockBean
private OauthClients oauthClients;
@Autowired
private MockMvc mockMvc;

@Autowired
private ObjectMapper objectMapper;

@Autowired
private MockMvc mockMvc;
@MockBean
private OauthClients oauthClients;

@Autowired
private JwtTokenProvider jwtTokenProvider;

@Autowired
private TokenConfig tokenConfig;

@Autowired
private WebApplicationContext webApplicationContext;

@BeforeEach
void setUp() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}

@Test
void 회원으로_스터디를_진행한다() throws Exception {
LoginResponse 로그인_정보 = 구글_로그인을_진행한다();
Expand Down Expand Up @@ -125,32 +112,31 @@ void setUp() {
참여_코드로_스터디_아이디를_얻는다(로그인_정보, 참여_코드);
}

private List<StudyResponse> 회원으로_진행했던_모든_스터디_목록을_조회한다(LoginResponse 로그인_정보)
throws Exception {
long memberId = Long.parseLong(jwtTokenProvider
.parseSubject(로그인_정보.tokenResponse().accessToken(), tokenConfig.secretKey()));
private List<StudyResponse> 회원으로_진행했던_모든_스터디_목록을_조회한다(LoginResponse 로그인_정보) throws Exception {
long memberId = Long.parseLong(
jwtTokenProvider.parseSubject(로그인_정보.tokenResponse().accessToken(), tokenConfig.secretKey()));

MvcResult result = mockMvc.perform(
get("/api/studies")
get("/api/v2/studies")
.param("memberId", String.valueOf(memberId))
.header(HttpHeaders.AUTHORIZATION, 로그인_정보.createAuthorizationHeader()))
.andExpect(status().isOk())
.andReturn();

String jsonResponse = result.getResponse().getContentAsString(StandardCharsets.UTF_8);
StudiesResponse StudiesResponse = objectMapper.readValue(jsonResponse,
StudiesResponse.class);
StudiesResponse StudiesResponse = objectMapper.readValue(jsonResponse, StudiesResponse.class);

return StudiesResponse.studies();
}

private LoginResponse 비회원_로그인을_진행한다() throws Exception {
MvcResult result = mockMvc.perform(post("/api/auth/guest"))
MvcResult result = mockMvc.perform(post("/api/v2/auth/guest"))
.andExpect(status().isOk())
.andReturn();

String jsonResponse = result.getResponse().getContentAsString(StandardCharsets.UTF_8);
TokenResponse tokenResponse = objectMapper.readValue(jsonResponse, TokenResponse.class);

return new LoginResponse(tokenResponse, null);
}

Expand All @@ -166,7 +152,7 @@ void setUp() {
"mock-picture"));

MvcResult result = mockMvc.perform(
post("/api/auth/login")
post("/api/v2/auth/login")
.contentType(MediaType.APPLICATION_JSON)
.content(jsonRequest))
.andExpect(status().isOk())
Expand All @@ -175,24 +161,25 @@ void setUp() {
String jsonResponse = result.getResponse().getContentAsString(StandardCharsets.UTF_8);
Cookie refreshToken = result.getResponse().getCookie("refreshToken");
TokenResponse tokenResponse = objectMapper.readValue(jsonResponse, TokenResponse.class);

return new LoginResponse(tokenResponse, refreshToken);
}

private Long 스터디를_개설한다(LoginResponse 로그인_정보) throws Exception {
CreateStudyRequest request = new CreateStudyRequest("studyName", 1, 20);
String jsonRequest = objectMapper.writeValueAsString(request);
MvcResult result = mockMvc.perform(
post("/api/studies")
post("/api/v2/studies")
.contentType(MediaType.APPLICATION_JSON)
.content(jsonRequest)
.header(HttpHeaders.AUTHORIZATION, 로그인_정보.createAuthorizationHeader()))
.andExpect(status().isCreated())
.andReturn();
String locationHeader = result.getResponse().getHeader(HttpHeaders.LOCATION);

String locationHeader = result.getResponse().getHeader(HttpHeaders.LOCATION);
String[] parsed = locationHeader.split("/");
System.out.println(locationHeader);
return Long.parseLong(parsed[3]);

return Long.parseLong(parsed[parsed.length - 1]);
}

private Long 스터디에_참여한다(LoginResponse 로그인_정보, Long 스터디_아이디) throws Exception {
Expand All @@ -202,7 +189,7 @@ void setUp() {
String jsonRequest = objectMapper.writeValueAsString(request);

MvcResult result = mockMvc.perform(
post("/api/studies/{studyId}/participants", 스터디_아이디)
post("/api/v2/studies/{studyId}/participants", 스터디_아이디)
.contentType(MediaType.APPLICATION_JSON)
.content(jsonRequest)
.header(HttpHeaders.AUTHORIZATION, 로그인_정보.createAuthorizationHeader()))
Expand All @@ -220,16 +207,15 @@ void setUp() {
WritePlanRequest request = new WritePlanRequest(참여자_아이디, Map.of("plan", "test"));
String jsonRequest = objectMapper.writeValueAsString(request);

mockMvc.perform(post("/api/studies/{studyId}/contents/write-plan", 스터디_아이디)
mockMvc.perform(post("/api/v2/studies/{studyId}/contents/write-plan", 스터디_아이디)
.contentType(MediaType.APPLICATION_JSON)
.content(jsonRequest)
.header(HttpHeaders.AUTHORIZATION, 로그인_정보.createAuthorizationHeader()))
.andExpect(status().isOk());
}

private void 스터디_상태를_다음_단계로_넘긴다(LoginResponse 로그인_정보, Long 스터디_아이디)
throws Exception {
mockMvc.perform(post("/api/studies/{studyId}/next-step", 스터디_아이디)
private void 스터디_상태를_다음_단계로_넘긴다(LoginResponse 로그인_정보, Long 스터디_아이디) throws Exception {
mockMvc.perform(post("/api/v2/studies/{studyId}/next-step", 스터디_아이디)
.header(HttpHeaders.AUTHORIZATION, 로그인_정보.createAuthorizationHeader()))
.andExpect(status().isNoContent());
}
Expand All @@ -239,16 +225,15 @@ void setUp() {
Map.of("retrospect", "test"));
String jsonRequest = objectMapper.writeValueAsString(request);

mockMvc.perform(post("/api/studies/{studyId}/contents/write-retrospect",
스터디_아이디)
mockMvc.perform(post("/api/v2/studies/{studyId}/contents/write-retrospect", 스터디_아이디)
.contentType(MediaType.APPLICATION_JSON)
.content(jsonRequest)
.header(HttpHeaders.AUTHORIZATION, 로그인_정보.createAuthorizationHeader()))
.andExpect(status().isOk());
}

private void 스터디_종료_후_결과_조회(LoginResponse 로그인_정보, Long 스터디_아이디) throws Exception {
MvcResult result = mockMvc.perform(get("/api/studies/{studyId}/participants", 스터디_아이디)
MvcResult result = mockMvc.perform(get("/api/v2/studies/{studyId}/participants", 스터디_아이디)
.accept(MediaType.APPLICATION_JSON)
.header(HttpHeaders.AUTHORIZATION, 로그인_정보.createAuthorizationHeader()))
.andExpect(status().isOk())
Expand All @@ -268,30 +253,31 @@ void setUp() {
}

private String 스터디_아이디로_참여_코드를_얻는다(LoginResponse 로그인_정보, Long 스터디_아이디) throws Exception {
MvcResult result = mockMvc.perform(get("/api/participant-codes")
MvcResult result = mockMvc.perform(get("/api/v2/participant-codes")
.param("studyId", 스터디_아이디.toString())
.accept(MediaType.APPLICATION_JSON)
.header(HttpHeaders.AUTHORIZATION, 로그인_정보.createAuthorizationHeader()))
.andExpect(status().isOk())
.andReturn();

String response = result.getResponse().getContentAsString(StandardCharsets.UTF_8);
ParticipantCodeResponse jsonResponse = objectMapper.readValue(response,
ParticipantCodeResponse.class);
ParticipantCodeResponse jsonResponse = objectMapper.readValue(response, ParticipantCodeResponse.class);

assertThat(jsonResponse.participantCode()).hasSize(6);
return jsonResponse.participantCode();
}

private void 참여_코드로_스터디_아이디를_얻는다(LoginResponse 로그인_정보, String 참여_코드) throws Exception {
MvcResult result = mockMvc.perform(get("/api/studies")
MvcResult result = mockMvc.perform(get("/api/v2/studies")
.param("participantCode", 참여_코드)
.accept(MediaType.APPLICATION_JSON)
.header(HttpHeaders.AUTHORIZATION, 로그인_정보.createAuthorizationHeader()))
.andExpect(status().isOk())
.andReturn();

String response = result.getResponse().getContentAsString(StandardCharsets.UTF_8);
Assertions.assertDoesNotThrow(() -> objectMapper.readValue(response,
StudyResponse.class));

assertThatCode(() -> objectMapper.readValue(response, StudyResponse.class))
.doesNotThrowAnyException();
Comment on lines +280 to +281
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저번에 마코랑은 얘기했었던 것 같은데 assertThatCode() + doesNotThrowAnyException()을 쓰는 이유가 있나요?
저는 assertDoesNotThrow()가 둘을 합친 것이라 생각해 가독성도 좋고 간결하다고 생각해서요

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요 부분은 지속적으로 팀 내에서 언급이 되는 사항이라 여겨지는데 이번 PR을 기점으로 컨벤션을 잡는 것이 좋을 것 같습니다. 이번 PR이 테스트 코드 리팩토링이기도 하구요!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

스타일 차이이긴 한데 저는 assertThatCode() 취향이기는 합니다.
다른 부분도 assertThat() + isEqualTo() 이런식으로 사용하니까 예외 검증하는 부분도 assertThatCode() + doesNotThrowxxx() 이런식으로 하는게 일관적이고 개인적으로는 읽기 편하다고 느낍니다.
하지만 큰 차이는 아니라서 팀이 결정한다면 어느 쪽이든 좋아요:)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 둘 다 상관은 없으나 이참에 컨벤션 정하는 게 나을 것 같네요 !

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

=> 팀 회의를 통해 둘 다 사용하는 방향으로 결정했습니다.

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,22 @@

import java.util.Map;

import harustudy.backend.testutils.EntityManagerUtil;
import harustudy.backend.testutils.EntityManagerUtils;
import jakarta.persistence.EntityManager;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayNameGeneration;
import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;

@SuppressWarnings("NonAsciiCharacters")
@DisplayNameGeneration(ReplaceUnderscores.class)
@DataJpaTest
class ContentRepositoryTest {

@Autowired
private TestEntityManager testEntityManager;
private EntityManager entityManager;

@Autowired
private ContentRepository contentRepository;
Expand All @@ -38,11 +38,11 @@ void setUp() {
Member member = new Member("member", "email", "imageUrl", LoginType.GUEST);
participant = Participant.createParticipantOfStudy(study, member, "nickname");

testEntityManager.persist(study);
testEntityManager.persist(member);
testEntityManager.persist(participant);
entityManager.persist(study);
entityManager.persist(member);
entityManager.persist(participant);

EntityManagerUtil.flushAndClearContext(testEntityManager);
EntityManagerUtils.flushAndClearContext(entityManager);
}

@Test
Expand All @@ -52,9 +52,9 @@ void setUp() {
"80%");
Content content = new Content(participant, 1);
content.changePlan(plan);
testEntityManager.persist(content);
entityManager.persist(content);

EntityManagerUtil.flushAndClearContext(testEntityManager);
EntityManagerUtils.flushAndClearContext(entityManager);

// when
Content found = contentRepository.findById(content.getId())
Expand All @@ -75,9 +75,9 @@ void setUp() {
Content content = new Content(participant, 1);
content.changePlan(plan);
content.changeRetrospect(retrospect);
testEntityManager.persist(content);
entityManager.persist(content);

EntityManagerUtil.flushAndClearContext(testEntityManager);
EntityManagerUtils.flushAndClearContext(entityManager);

// when
Content found = contentRepository.findById(content.getId())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import harustudy.backend.participant.exception.StudyStepException;
import harustudy.backend.study.domain.Study;
import harustudy.backend.study.exception.StudyNotFoundException;
import harustudy.backend.testutils.EntityManagerUtil;
import harustudy.backend.testutils.EntityManagerUtils;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import java.util.List;
Expand Down Expand Up @@ -61,7 +61,7 @@ void setUp() {
entityManager.persist(participant);
entityManager.persist(content);

EntityManagerUtil.flushAndClearContext(entityManager);
EntityManagerUtils.flushAndClearContext(entityManager);
}

@Test
Expand All @@ -73,7 +73,7 @@ void setUp() {
study.proceed();

entityManager.merge(study);
EntityManagerUtil.flushAndClearContext(entityManager);
EntityManagerUtils.flushAndClearContext(entityManager);

WritePlanRequest request = new WritePlanRequest(participant.getId(),
Map.of("plan", "abc"));
Expand All @@ -90,7 +90,7 @@ void setUp() {
study.proceed();

entityManager.merge(study);
EntityManagerUtil.flushAndClearContext(entityManager);
EntityManagerUtils.flushAndClearContext(entityManager);

AuthMember authMember = new AuthMember(member.getId());
WritePlanRequest request = new WritePlanRequest(participant.getId(),
Expand All @@ -110,7 +110,7 @@ void setUp() {
study.proceed();

entityManager.merge(study);
EntityManagerUtil.flushAndClearContext(entityManager);
EntityManagerUtils.flushAndClearContext(entityManager);

AuthMember authMember = new AuthMember(member.getId());
WriteRetrospectRequest request = new WriteRetrospectRequest(participant.getId(),
Expand Down Expand Up @@ -148,7 +148,7 @@ void setUp() {

entityManager.merge(content);
entityManager.merge(study);
EntityManagerUtil.flushAndClearContext(entityManager);
EntityManagerUtils.flushAndClearContext(entityManager);

WriteRetrospectRequest request = new WriteRetrospectRequest(participant.getId(),
Map.of("retrospect", "abc"));
Expand All @@ -169,7 +169,7 @@ void setUp() {
content.changeRetrospect(retrospect);

entityManager.merge(content);
EntityManagerUtil.flushAndClearContext(entityManager);
EntityManagerUtils.flushAndClearContext(entityManager);

// when
ContentsResponse contentsResponse =
Expand Down Expand Up @@ -207,7 +207,7 @@ void setUp() {
entityManager.merge(study);
entityManager.merge(content);
entityManager.persist(anotherContent);
EntityManagerUtil.flushAndClearContext(entityManager);
EntityManagerUtils.flushAndClearContext(entityManager);

// when
ContentsResponse contentsResponse = contentService.findContentsWithFilter(authMember,
Expand Down
Loading