From 27030c110bf0f98eb7af3cca369fbd411b7899d7 Mon Sep 17 00:00:00 2001 From: KyungMin Lee Date: Tue, 13 Aug 2024 13:55:27 +0900 Subject: [PATCH 1/5] =?UTF-8?q?chore:=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ProjectService.updateProjectValues의 파라미터를 변경했습니다. --- .../domain/project/application/ProjectService.java | 7 +++---- .../project/application/ProjectServiceTest.java | 11 ++++------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/logbat/src/main/java/info/logbat/domain/project/application/ProjectService.java b/logbat/src/main/java/info/logbat/domain/project/application/ProjectService.java index 7371a19..d4597cf 100644 --- a/logbat/src/main/java/info/logbat/domain/project/application/ProjectService.java +++ b/logbat/src/main/java/info/logbat/domain/project/application/ProjectService.java @@ -1,7 +1,6 @@ package info.logbat.domain.project.application; import info.logbat.domain.project.domain.Project; -import info.logbat.domain.project.presentation.payload.request.ProjectUpdateRequest; import info.logbat.domain.project.presentation.payload.response.ProjectCommonResponse; import info.logbat.domain.project.repository.ProjectJpaRepository; import lombok.RequiredArgsConstructor; @@ -27,9 +26,9 @@ public ProjectCommonResponse getProjectByName(String name) { return ProjectCommonResponse.from(project); } - public ProjectCommonResponse updateProjectValues(ProjectUpdateRequest request) { - Project project = getProject(request.id()); - project.updateName(request.name()); + public ProjectCommonResponse updateProjectValues(Long id, String name) { + Project project = getProject(id); + project.updateName(name); return ProjectCommonResponse.from(project); } diff --git a/logbat/src/test/java/info/logbat/domain/project/application/ProjectServiceTest.java b/logbat/src/test/java/info/logbat/domain/project/application/ProjectServiceTest.java index f54c379..0ad2387 100644 --- a/logbat/src/test/java/info/logbat/domain/project/application/ProjectServiceTest.java +++ b/logbat/src/test/java/info/logbat/domain/project/application/ProjectServiceTest.java @@ -8,7 +8,6 @@ import static org.mockito.Mockito.spy; import info.logbat.domain.project.domain.Project; -import info.logbat.domain.project.presentation.payload.request.ProjectUpdateRequest; import info.logbat.domain.project.presentation.payload.response.ProjectCommonResponse; import info.logbat.domain.project.repository.ProjectJpaRepository; import java.time.LocalDateTime; @@ -106,15 +105,14 @@ class whenUpdateProject { void canUpdateProjectValues() { // Arrange LocalDateTime expectedUpdatedAt = LocalDateTime.now(); - ProjectUpdateRequest request = new ProjectUpdateRequest(expectedProjectId, - expectedUpdatedProjectName); given(projectRepository.findById(expectedProjectId)).willReturn( Optional.of(expectedProject)); given(expectedProject.getId()).willReturn(expectedProjectId); given(expectedProject.getCreatedAt()).willReturn(expectedCreatedAt); given(expectedProject.getUpdatedAt()).willReturn(expectedUpdatedAt); // Act - ProjectCommonResponse actualResult = projectService.updateProjectValues(request); + ProjectCommonResponse actualResult = projectService.updateProjectValues( + expectedProjectId, expectedUpdatedProjectName); // Assert assertThat(actualResult) .extracting("id", "name", "createdAt", "updatedAt") @@ -128,11 +126,10 @@ void canUpdateProjectValues() { void cannotUpdateProjectValues() { // Arrange Long expectedWrongProjectId = 2L; - ProjectUpdateRequest request = new ProjectUpdateRequest(expectedWrongProjectId, - expectedUpdatedProjectName); given(projectRepository.findById(expectedWrongProjectId)).willReturn(Optional.empty()); // Act & Assert - assertThatThrownBy(() -> projectService.updateProjectValues(request)) + assertThatThrownBy(() -> projectService.updateProjectValues(expectedWrongProjectId, + expectedUpdatedProjectName)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("프로젝트를 찾을 수 없습니다."); } From 431d4e8b072b8032e5f072f7b88fa7d722ab24a4 Mon Sep 17 00:00:00 2001 From: KyungMin Lee Date: Tue, 13 Aug 2024 14:06:00 +0900 Subject: [PATCH 2/5] =?UTF-8?q?feat:=20=EA=B3=B5=ED=86=B5=20=EC=9D=91?= =?UTF-8?q?=EB=8B=B5=20=EA=B7=9C=EA=B2=A9=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 공통 응답 규격인 ApiCommonResponse를 구현했습니다. --- .../common/payload/ApiCommonResponse.java | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 logbat/src/main/java/info/logbat/common/payload/ApiCommonResponse.java diff --git a/logbat/src/main/java/info/logbat/common/payload/ApiCommonResponse.java b/logbat/src/main/java/info/logbat/common/payload/ApiCommonResponse.java new file mode 100644 index 0000000..68c8d8c --- /dev/null +++ b/logbat/src/main/java/info/logbat/common/payload/ApiCommonResponse.java @@ -0,0 +1,48 @@ +package info.logbat.common.payload; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.http.HttpStatus; + +@Getter +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class ApiCommonResponse { + + private int statusCode; + private String message; + private T data; + + private ApiCommonResponse(int status, String message, T data) { + this.statusCode = status; + this.message = message; + this.data = data; + } + + private ApiCommonResponse(int statusCode, String message) { + this.statusCode = statusCode; + this.message = message; + } + + private ApiCommonResponse(int statusCode) { + this.statusCode = statusCode; + } + + public static ApiCommonResponse createApiResponse(HttpStatus httpStatus, String message, + T data) { + return new ApiCommonResponse<>(httpStatus.value(), message, data); + } + + public static ApiCommonResponse createFailResponse(HttpStatus httpStatus, + String message) { + return new ApiCommonResponse<>(httpStatus.value(), message); + } + + public static ApiCommonResponse createSuccessResponse() { + return new ApiCommonResponse<>(HttpStatus.OK.value()); + } + + public static ApiCommonResponse createSuccessResponse(T data) { + return new ApiCommonResponse<>(HttpStatus.OK.value(), "Success", data); + } +} From ab594cd4cd2e481f38f3fdd001458eddd81e3556 Mon Sep 17 00:00:00 2001 From: KyungMin Lee Date: Tue, 13 Aug 2024 14:32:34 +0900 Subject: [PATCH 3/5] =?UTF-8?q?feat:=20Project=20Controller=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Project API Controller를 구현했습니다. (URI: `/v1/projects`) - GET `/{name}`: 프로젝트 조회 - POST `/`: 프로젝트 생성 - PUT `/{id}`: 프로젝트 수정 - DELETE `/{id}`: 프로젝트 제거 --- .../presentation/ProjectController.java | 53 +++++++++++++++++++ .../payload/request/ProjectCreateRequest.java | 5 ++ .../payload/request/ProjectUpdateRequest.java | 2 +- 3 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 logbat/src/main/java/info/logbat/domain/project/presentation/ProjectController.java create mode 100644 logbat/src/main/java/info/logbat/domain/project/presentation/payload/request/ProjectCreateRequest.java diff --git a/logbat/src/main/java/info/logbat/domain/project/presentation/ProjectController.java b/logbat/src/main/java/info/logbat/domain/project/presentation/ProjectController.java new file mode 100644 index 0000000..0c41dbe --- /dev/null +++ b/logbat/src/main/java/info/logbat/domain/project/presentation/ProjectController.java @@ -0,0 +1,53 @@ +package info.logbat.domain.project.presentation; + +import info.logbat.common.payload.ApiCommonResponse; +import info.logbat.domain.project.application.ProjectService; +import info.logbat.domain.project.presentation.payload.request.ProjectCreateRequest; +import info.logbat.domain.project.presentation.payload.request.ProjectUpdateRequest; +import info.logbat.domain.project.presentation.payload.response.ProjectCommonResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/v1/projects") +@RequiredArgsConstructor +public class ProjectController { + + private final ProjectService projectService; + + @GetMapping("/{name}") + public ApiCommonResponse get(@PathVariable String name) { + return ApiCommonResponse.createSuccessResponse(projectService.getProjectByName(name)); + } + + @PostMapping + public ResponseEntity> create( + @RequestBody ProjectCreateRequest request) { + ApiCommonResponse response = ApiCommonResponse.createSuccessResponse( + projectService.createProject(request.name())); + return ResponseEntity.status(HttpStatus.CREATED).body(response); + } + + @PutMapping("/{id}") + public ApiCommonResponse update(@PathVariable Long id, + @RequestBody ProjectUpdateRequest request) { + return ApiCommonResponse.createSuccessResponse( + projectService.updateProjectValues(id, request.name())); + } + + @DeleteMapping("/{id}") + public ApiCommonResponse delete(@PathVariable Long id) { + Long expectedId = projectService.deleteProject(id); + return ApiCommonResponse.createSuccessResponse(expectedId); + } + +} diff --git a/logbat/src/main/java/info/logbat/domain/project/presentation/payload/request/ProjectCreateRequest.java b/logbat/src/main/java/info/logbat/domain/project/presentation/payload/request/ProjectCreateRequest.java new file mode 100644 index 0000000..dad036c --- /dev/null +++ b/logbat/src/main/java/info/logbat/domain/project/presentation/payload/request/ProjectCreateRequest.java @@ -0,0 +1,5 @@ +package info.logbat.domain.project.presentation.payload.request; + +public record ProjectCreateRequest(String name) { + +} diff --git a/logbat/src/main/java/info/logbat/domain/project/presentation/payload/request/ProjectUpdateRequest.java b/logbat/src/main/java/info/logbat/domain/project/presentation/payload/request/ProjectUpdateRequest.java index 401ffef..6261346 100644 --- a/logbat/src/main/java/info/logbat/domain/project/presentation/payload/request/ProjectUpdateRequest.java +++ b/logbat/src/main/java/info/logbat/domain/project/presentation/payload/request/ProjectUpdateRequest.java @@ -1,5 +1,5 @@ package info.logbat.domain.project.presentation.payload.request; -public record ProjectUpdateRequest(Long id, String name) { +public record ProjectUpdateRequest(String name) { } From 48165ff92fe82253d058e8ac184d7da925895996 Mon Sep 17 00:00:00 2001 From: KyungMin Lee Date: Tue, 13 Aug 2024 15:47:39 +0900 Subject: [PATCH 4/5] =?UTF-8?q?test:=20Project=20Controller=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `@WebMvcTest` 기반 ProjectController 테스트를 진행했습니다. --- .../presentation/ProjectController.java | 4 +- .../domain/common/ControllerTestSupport.java | 26 ++-- .../presentation/ProjectControllerTest.java | 146 ++++++++++++++++++ 3 files changed, 160 insertions(+), 16 deletions(-) create mode 100644 logbat/src/test/java/info/logbat/domain/project/presentation/ProjectControllerTest.java diff --git a/logbat/src/main/java/info/logbat/domain/project/presentation/ProjectController.java b/logbat/src/main/java/info/logbat/domain/project/presentation/ProjectController.java index 0c41dbe..f5e08ba 100644 --- a/logbat/src/main/java/info/logbat/domain/project/presentation/ProjectController.java +++ b/logbat/src/main/java/info/logbat/domain/project/presentation/ProjectController.java @@ -32,8 +32,8 @@ public ApiCommonResponse get(@PathVariable String name) { @PostMapping public ResponseEntity> create( @RequestBody ProjectCreateRequest request) { - ApiCommonResponse response = ApiCommonResponse.createSuccessResponse( - projectService.createProject(request.name())); + ApiCommonResponse response = ApiCommonResponse.createApiResponse( + HttpStatus.CREATED, "Success", projectService.createProject(request.name())); return ResponseEntity.status(HttpStatus.CREATED).body(response); } diff --git a/logbat/src/test/java/info/logbat/domain/common/ControllerTestSupport.java b/logbat/src/test/java/info/logbat/domain/common/ControllerTestSupport.java index 57beca5..bd497b5 100644 --- a/logbat/src/test/java/info/logbat/domain/common/ControllerTestSupport.java +++ b/logbat/src/test/java/info/logbat/domain/common/ControllerTestSupport.java @@ -3,33 +3,31 @@ import com.fasterxml.jackson.databind.ObjectMapper; import info.logbat.domain.log.application.LogService; import info.logbat.domain.log.presentation.LogController; +import info.logbat.domain.project.presentation.ProjectController; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; -/** +/* * 이후 테스트 하려면 Controller에 대해 controllers에 추가하고, ControllerTestSupport를 상속받아 테스트를 진행하시면 됩니다. */ -@WebMvcTest(controllers = { - LogController.class -} -) +@WebMvcTest(controllers = {LogController.class, ProjectController.class}) @ActiveProfiles("test") public abstract class ControllerTestSupport { - @Autowired - protected MockMvc mockMvc; + @Autowired + protected MockMvc mockMvc; - @Autowired - protected ObjectMapper objectMapper; + @Autowired + protected ObjectMapper objectMapper; - @MockBean - protected LogService logService; + @MockBean + protected LogService logService; - /** - * 이후 필요한 서비스에 대해 MockBean을 추가하여 테스트를 진행하시면 됩니다. - */ + /* + * 이후 필요한 서비스에 대해 MockBean을 추가하여 테스트를 진행하시면 됩니다. + */ } \ No newline at end of file diff --git a/logbat/src/test/java/info/logbat/domain/project/presentation/ProjectControllerTest.java b/logbat/src/test/java/info/logbat/domain/project/presentation/ProjectControllerTest.java new file mode 100644 index 0000000..db6ffe5 --- /dev/null +++ b/logbat/src/test/java/info/logbat/domain/project/presentation/ProjectControllerTest.java @@ -0,0 +1,146 @@ +package info.logbat.domain.project.presentation; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import info.logbat.domain.common.ControllerTestSupport; +import info.logbat.domain.project.application.ProjectService; +import info.logbat.domain.project.presentation.payload.response.ProjectCommonResponse; +import java.time.LocalDateTime; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; + +@ExtendWith(MockitoExtension.class) +@DisplayName("ProjectController는") +class ProjectControllerTest extends ControllerTestSupport { + + @MockBean + private ProjectService projectService; + + private final Long expectedId = 1L; + private final String expectedName = "projectName"; + private final ProjectCommonResponse projectCommonResponse = mock(ProjectCommonResponse.class); + + @Nested + @DisplayName("GET /v1/projects/{name}에 대해") + class describeGet { + + @Test + @DisplayName("프로젝트 이름으로 프로젝트를 조회할 수 있다.") + void willReturnProjectInformation() throws Exception { + // Arrange + LocalDateTime expectedCreatedAt = LocalDateTime.now(); + given(projectService.getProjectByName("projectName")).willReturn(projectCommonResponse); + given(projectCommonResponse.id()).willReturn(expectedId); + given(projectCommonResponse.name()).willReturn(expectedName); + given(projectCommonResponse.createdAt()).willReturn(expectedCreatedAt); + // Act + MockHttpServletRequestBuilder get = get("/v1/projects/{name}", "projectName"); + // Assert + mockMvc.perform(get) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.statusCode").value(200)) + .andExpect(jsonPath("$.message").value("Success")) + .andExpect(jsonPath("$.data.id").value(expectedId)) + .andExpect(jsonPath("$.data.name").value(expectedName)) + .andExpect(jsonPath("$.data.createdAt").value(expectedCreatedAt.toString())) + .andExpect(jsonPath("$.data.updatedAt").doesNotExist()); + } + + } + + @Nested + @DisplayName("POST /v1/projects에 대해") + class describePost { + + @Test + @DisplayName("프로젝트를 생성할 수 있다.") + void willCreateProject() throws Exception { + // Arrange + LocalDateTime expectedCreatedAt = LocalDateTime.now(); + given(projectService.createProject(expectedName)).willReturn(projectCommonResponse); + given(projectCommonResponse.id()).willReturn(expectedId); + given(projectCommonResponse.name()).willReturn(expectedName); + given(projectCommonResponse.createdAt()).willReturn(expectedCreatedAt); + // Act + MockHttpServletRequestBuilder post = post("/v1/projects") + .contentType("application/json") + .content("{\"name\":\"" + expectedName + "\"}"); + // Assert + mockMvc.perform(post) + .andExpect(status().isCreated()) + .andExpect(jsonPath("$.statusCode").value(201)) + .andExpect(jsonPath("$.message").value("Success")) + .andExpect(jsonPath("$.data.id").value(expectedId)) + .andExpect(jsonPath("$.data.name").value(expectedName)) + .andExpect(jsonPath("$.data.createdAt").value(expectedCreatedAt.toString())) + .andExpect(jsonPath("$.data.updatedAt").doesNotExist()); + } + + } + + @Nested + @DisplayName("PUT /v1/projects/{id}에 대해") + class describePut { + + @Test + @DisplayName("프로젝트를 수정할 수 있다.") + void willUpdateProject() throws Exception { + // Arrange + LocalDateTime expectedCreatedAt = LocalDateTime.now(); + given(projectService.updateProjectValues(expectedId, expectedName)).willReturn( + projectCommonResponse); + given(projectCommonResponse.id()).willReturn(expectedId); + given(projectCommonResponse.name()).willReturn(expectedName); + given(projectCommonResponse.createdAt()).willReturn(expectedCreatedAt); + // Act + MockHttpServletRequestBuilder put = put("/v1/projects/{id}", expectedId) + .contentType("application/json") + .content("{\"name\":\"" + expectedName + "\"}"); + // Assert + mockMvc.perform(put) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.statusCode").value(200)) + .andExpect(jsonPath("$.message").value("Success")) + .andExpect(jsonPath("$.data.id").value(expectedId)) + .andExpect(jsonPath("$.data.name").value(expectedName)) + .andExpect(jsonPath("$.data.createdAt").value(expectedCreatedAt.toString())) + .andExpect(jsonPath("$.data.updatedAt").doesNotExist()); + } + + } + + @Nested + @DisplayName("DELETE /v1/projects/{id}에 대해") + class describeDelete { + + @Test + @DisplayName("프로젝트를 삭제할 수 있다.") + void willDeleteProject() throws Exception { + // Arrange + given(projectService.deleteProject(any(Long.class))).willReturn(expectedId); + // Act + MockHttpServletRequestBuilder delete = delete("/v1/projects/{id}", expectedId); + // Assert + mockMvc.perform(delete) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.statusCode").value(200)) + .andExpect(jsonPath("$.message").value("Success")) + .andExpect(jsonPath("$.data").value(expectedId)); + } + + } + +} \ No newline at end of file From b3df42fa8021ca2b44e0983f266a0c02dde6d808 Mon Sep 17 00:00:00 2001 From: KyungMin Lee Date: Tue, 13 Aug 2024 16:05:59 +0900 Subject: [PATCH 5/5] =?UTF-8?q?chore:=20ControllerTestSupport=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ProjectService MockBean 이동 --- .../info/logbat/domain/common/ControllerTestSupport.java | 4 ++++ .../domain/project/presentation/ProjectControllerTest.java | 5 ----- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/logbat/src/test/java/info/logbat/domain/common/ControllerTestSupport.java b/logbat/src/test/java/info/logbat/domain/common/ControllerTestSupport.java index bd497b5..a1173f7 100644 --- a/logbat/src/test/java/info/logbat/domain/common/ControllerTestSupport.java +++ b/logbat/src/test/java/info/logbat/domain/common/ControllerTestSupport.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import info.logbat.domain.log.application.LogService; import info.logbat.domain.log.presentation.LogController; +import info.logbat.domain.project.application.ProjectService; import info.logbat.domain.project.presentation.ProjectController; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; @@ -26,6 +27,9 @@ public abstract class ControllerTestSupport { @MockBean protected LogService logService; + @MockBean + protected ProjectService projectService; + /* * 이후 필요한 서비스에 대해 MockBean을 추가하여 테스트를 진행하시면 됩니다. */ diff --git a/logbat/src/test/java/info/logbat/domain/project/presentation/ProjectControllerTest.java b/logbat/src/test/java/info/logbat/domain/project/presentation/ProjectControllerTest.java index db6ffe5..13c1f6d 100644 --- a/logbat/src/test/java/info/logbat/domain/project/presentation/ProjectControllerTest.java +++ b/logbat/src/test/java/info/logbat/domain/project/presentation/ProjectControllerTest.java @@ -11,7 +11,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import info.logbat.domain.common.ControllerTestSupport; -import info.logbat.domain.project.application.ProjectService; import info.logbat.domain.project.presentation.payload.response.ProjectCommonResponse; import java.time.LocalDateTime; import org.junit.jupiter.api.DisplayName; @@ -19,16 +18,12 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; @ExtendWith(MockitoExtension.class) @DisplayName("ProjectController는") class ProjectControllerTest extends ControllerTestSupport { - @MockBean - private ProjectService projectService; - private final Long expectedId = 1L; private final String expectedName = "projectName"; private final ProjectCommonResponse projectCommonResponse = mock(ProjectCommonResponse.class);