-
Notifications
You must be signed in to change notification settings - Fork 89
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
3주차 테스트 작성하기 #100
base: tmxhsk99
Are you sure you want to change the base?
3주차 테스트 작성하기 #100
Changes from 1 commit
b8f5615
4f661a9
6da3a44
e1146dc
e468b67
04673fd
a0c183d
a645d9a
0586f34
1c0cc3f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package com.codesoom.assignment.application; | ||
|
||
import com.codesoom.assignment.TaskNotFoundException; | ||
import com.codesoom.assignment.models.Task; | ||
import org.assertj.core.api.Assertions; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Test; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.test.context.SpringBootTest; | ||
import org.springframework.boot.test.mock.mockito.MockBean; | ||
|
||
import static org.junit.jupiter.api.Assertions.*; | ||
import static org.mockito.BDDMockito.given; | ||
|
||
@SpringBootTest | ||
class TaskServiceTest { | ||
@Autowired | ||
TaskService taskService; | ||
|
||
@BeforeEach | ||
void setUp() { | ||
for (int i = 0; i < 10; i++) { | ||
Task task = new Task(); | ||
task.setTitle("task" + i); | ||
taskService.createTask(task); | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 할 일의 10개를 만들어 놓고 테스트를 작성해 주셨네요. 아마도 좀 더 진짜 같은 테트스를 작성하고 싶으셨을 것 같아요. 할 일이 1개이든 10개이든 같은 부류의 입력값이기 때문에 10개를 추가한다고 해서 테스트의 품질이 좋아지지는 않아요. 테스트를 작성할 때는 입력이나 출력이 어떤 부류에 속하는지 생각해 보면 좋습니다. 참고
|
||
|
||
@Test | ||
@DisplayName("할일 조회 리스트 성공 테스트") | ||
void getTasksSuccess() { | ||
Assertions.assertThat(taskService.getTasks()).hasSize(10); | ||
} | ||
|
||
@Test | ||
@DisplayName("할일 상세 조회 성공 테스트") | ||
void getTaskSuccess(){ | ||
Assertions.assertThat(taskService.getTask(1L).getTitle()).isEqualTo("task0"); | ||
} | ||
|
||
@Test | ||
@DisplayName("할일 상세 조회시 할일이 없는 경우") | ||
void getTaskFail(){ | ||
Assertions.assertThatThrownBy(() -> taskService.getTask(100L)).isInstanceOf(TaskNotFoundException.class); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
package com.codesoom.assignment.controllers; | ||
|
||
import com.codesoom.assignment.TaskNotFoundException; | ||
import com.codesoom.assignment.application.TaskService; | ||
import com.codesoom.assignment.models.Task; | ||
import org.assertj.core.api.Assertions; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Test; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; | ||
|
||
|
||
class TaskControllerTest { | ||
private TaskController taskController; | ||
|
||
@BeforeEach | ||
void setUp() { | ||
taskController = new TaskController(new TaskService()); | ||
} | ||
|
||
public Task createTask() { | ||
Task task = new Task(); | ||
task.setTitle("task"); | ||
return task; | ||
} | ||
|
||
private void createTasks() { | ||
for (int i = 1; i <= 10; i++) { | ||
Task task = new Task(); | ||
task.setTitle("task" + i); | ||
taskController.create(task); | ||
} | ||
} | ||
|
||
@Test | ||
@DisplayName("할일 생성 성공 테스트.") | ||
void createTaskSuccessTest() { | ||
Task task = createTask(); | ||
taskController.create(task); | ||
Assertions.assertThat(taskController.list()).hasSize(1); | ||
} | ||
|
||
@Test | ||
@DisplayName("최초 할일 리스트가 비어있는지 테스트.") | ||
void isFirstTasksIsEmpty() { | ||
Assertions.assertThat(taskController.list()).isEmpty(); | ||
} | ||
|
||
@Test | ||
@DisplayName("할일 리스트가 정상적으로 나오는 지 테스트한다.") | ||
void listSuccessTest() { | ||
createTasks(); | ||
Assertions.assertThat(taskController.list()).hasSize(10); | ||
} | ||
|
||
|
||
@Test | ||
@DisplayName("할일 상세 조회 성공 테스트") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 만약에 이 테스트가 실패해서 이런 메시지가 나왔다고 가정해 보겠습니다.
위에 테스트는 실패했다라는 피드백을 받을 수 있습니다. 하지만 원래 기대했던 바가 무엇이었는지 모르기 때문에 테스트 코드를 보고 원래 기대했던 바와 지금 현재 상황이 왜 틀린지 살펴본 후 문제를 수정해야 합니다. 테스트를 명확하게 잘 짜는 것도 중요하지만 테스트가 실패했을 때 빠르게 알아차릴 수 있는 것도 중요합니다. 따라서 이 테스트는 무엇을 테스트하고 있고, 어떠한 경우에 무엇을 기대하는지 작성해주는게 좋을 것 같습니다. 이럴 때 좋은 프레임워크가 있는데요. 바로 Given When Then입니다. ~것이 주어졌을 때(Given) ~하면(When) ~그래서 어떤 상태가 된다. 혹은 결과가 나온다.(Then) |
||
void getTaskSuccess() { | ||
createTasks(); | ||
Assertions.assertThat(taskController.detail(4L).getTitle()).isEqualTo("task4"); | ||
} | ||
|
||
@Test | ||
@DisplayName("할일 상세 조회 실패 테스트") | ||
void getTaskFail() { | ||
createTasks(); | ||
Assertions.assertThatThrownBy(() -> taskController.detail(100L)) | ||
.isInstanceOf(TaskNotFoundException.class); | ||
} | ||
|
||
@Test | ||
@DisplayName("할일 수정 성공 테스트") | ||
void updateTaskTest() { | ||
Task task = taskController.create(createTask()); | ||
Task updateTask = new Task(); | ||
updateTask.setTitle("updated"); | ||
taskController.update(task.getId(), updateTask); | ||
Assertions.assertThat(taskController.detail(task.getId()).getTitle()).isEqualTo("updated"); | ||
} | ||
|
||
@Test | ||
@DisplayName("할일 수정 실패 테스트") | ||
void updatedFailTest() { | ||
Task task = taskController.create(createTask()); | ||
Task updateTask = new Task(); | ||
updateTask.setTitle("updated"); | ||
taskController.update(task.getId(), updateTask); | ||
Assertions.assertThatThrownBy(() -> taskController.update(100L, updateTask)) | ||
.isInstanceOf(TaskNotFoundException.class); | ||
} | ||
|
||
@Test | ||
@DisplayName("할일 삭제 성공 테스트") | ||
void deleteTaskSuccess() { | ||
taskController.create(createTask()); | ||
taskController.delete(1L); | ||
Assertions.assertThat(taskController.list()).isEmpty(); | ||
} | ||
|
||
@Test | ||
@DisplayName("할일 삭제 실패 테스트") | ||
void deleteTaskFail() { | ||
Assertions.assertThatThrownBy(() -> taskController.delete(1L)).isInstanceOf(TaskNotFoundException.class); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package com.codesoom.assignment.controllers; | ||
|
||
import com.codesoom.assignment.TaskNotFoundException; | ||
import com.codesoom.assignment.application.TaskService; | ||
import com.codesoom.assignment.models.Task; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.Test; | ||
import org.mockito.BDDMockito; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; | ||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; | ||
import org.springframework.boot.test.context.SpringBootTest; | ||
import org.springframework.boot.test.mock.mockito.MockBean; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.test.web.client.match.MockRestRequestMatchers; | ||
import org.springframework.test.web.servlet.MockMvc; | ||
import org.springframework.test.web.servlet.ResultMatcher; | ||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; | ||
import org.springframework.test.web.servlet.result.MockMvcResultHandlers; | ||
import static org.hamcrest.Matchers.containsString; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import static org.mockito.BDDMockito.*; | ||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; | ||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; | ||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; | ||
|
||
@SpringBootTest | ||
@AutoConfigureMockMvc | ||
class TaskControllerWebTest { | ||
@Autowired | ||
private MockMvc mockMvc; | ||
|
||
@MockBean | ||
private TaskService taskService; | ||
|
||
@BeforeEach | ||
void setUp() { | ||
List<Task> tasks = new ArrayList<>(); | ||
Task task = new Task(); | ||
task.setTitle("test task"); | ||
tasks.add(task); | ||
|
||
given(taskService.getTasks()).willReturn(tasks); | ||
|
||
given(taskService.getTask(1L)).willReturn(task); | ||
|
||
given(taskService.getTask(100L)) | ||
.willThrow(new TaskNotFoundException(100L)); | ||
} | ||
@Test | ||
void list() throws Exception { | ||
mockMvc.perform(get("/tasks")) | ||
.andExpect((status().isOk())) | ||
.andExpect(content().string(containsString("test task"))); | ||
} | ||
|
||
@Test | ||
void detailWithValidId() throws Exception { | ||
mockMvc.perform(get("/tasks/1")) | ||
.andExpect(status().isOk()); | ||
} | ||
|
||
@Test | ||
void detailWithInvalidId() throws Exception { | ||
mockMvc.perform(get("/tasks/100")) | ||
.andExpect(status().isNotFound()); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@SpringBootTest
는 스프링 부트 애플리케이션의 모든 빈을 로드하는 매우 포괄적인 테스트를 위한 어노테이션인데, 이로 인해 테스트 실행 시간이 길어질 수 있습니다. 또한, 모든 빈을 로드하는 것은 불필요한 의존성 문제를 일으킬 수 있습니다.만약 Mock을 이용해서 테스트를 진행하면 빈을 로드하지 않아도 될 수도 있고 혹은 통합 테스트를 작성해서 레이어 간의 동작하는 것을 테스트하고 싶으시다면
@DataJpaTest
를 사용할 수 있어요.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
최초에 빈으로 로드하는 방식으로 했다가
그냥 테스트마다 Service를 생성하는 방식으로 변경했는데
지우는걸 잊었던 것 같습니다
제거하겠습니다.