728x90
Spring Boot REST APIs 테스트
status code
content type
JSON response body
를 어떻게 테스트 할 수 있을 까
전체코드
@TestPropertySource("/application-test.properties")
@AutoConfigureMockMvc
@SpringBootTest
@Transactional // JPA Entity Manager 사용
public class GradebookControllerTest
{
private static MockHttpServletRequest request;
@PersistenceContext
private EntityManager em;
@Mock
StudentAndGradeService studentAndGradeService;
@Autowired
private JdbcTemplate jdbc;
@Autowired
private StudentDao studentDao;
@Autowired
private MathGradesDao mathGradeDao;
@Autowired
private ScienceGradesDao scienceGradeDao;
@Autowired
private HistoryGradesDao historyGradeDao;
@Autowired
private StudentAndGradeService studentService;
@Autowired
private MockMvc mockMvc;
// is from Jackson API
// writeValueAsString() will generate a JSON string the java object
@Autowired
private ObjectMapper objectMapper;
@Autowired
private CollegeStudent student;
@Value("${sql.script.create.student}")
private String sqlAddStudent;
@Value("${sql.script.create.math.grade}")
private String sqlAddMathGrade;
@Value("${sql.script.create.science.grade}")
private String sqlAddScienceGrade;
@Value("${sql.script.create.history.grade}")
private String sqlAddHistoryGrade;
@Value("${sql.script.delete.student}")
private String sqlDeleteStudent;
@Value("${sql.script.delete.math.grade}")
private String sqlDeleteMathGrade;
@Value("${sql.script.delete.science.grade}")
private String sqlDeleteScienceGrade;
@Value("${sql.script.delete.history.grade}")
private String sqlDeleteHistoryGrade;
public static final MediaType APPLICATION_JSON_UTF8 = MediaType.APPLICATION_JSON;
@BeforeAll
public static void setUp(){
request = new MockHttpServletRequest();
request.setParameter("firstname", "java");
request.setParameter("lastname","app");
request.setParameter("emailAddress","javapp.tistory.com");
}
@BeforeEach
public void setupDatabase() {
jdbc.execute(sqlAddStudent);
jdbc.execute(sqlAddMathGrade);
jdbc.execute(sqlAddScienceGrade);
jdbc.execute(sqlAddHistoryGrade);
}
//
@Test
public void getStudentHttpRequest() throws Exception
{
mockMvc.perform(MockMvcRequestBuilders.get("/"))
.andExpect(status().isOk())
.andExpect(content().contentType(APPLICATION_JSON_UTF8))
.andExpect(jsonPath("$",hasSize(1)));
}
@Test
public void 학생생성_HttpRequest() throws Exception
{
// given
student.setFirstname("java");
student.setLastname("app");
student.setEmailAddress("javapp@tistory.com");
//when
mockMvc.perform(post("/")
.contentType(APPLICATION_JSON_UTF8)
.content(objectMapper.writeValueAsString(student)))
.andExpect(status().isOk())
.andExpect(jsonPath("$",hasSize(2)));
// then, 검증
CollegeStudent verifyStudent = studentDao.findByEmailAddress("javapp@tistory.com");
assertNotNull(verifyStudent, "유효한 학생");
}
@Test
public void 학생삭제_HttpRequest() throws Exception
{
assertTrue(studentDao.findById(1).isPresent());
mockMvc.perform(MockMvcRequestBuilders.delete("/stduent/{id}",1))
.andExpect(status().isOk())
.andExpect(content().contentType(APPLICATION_JSON_UTF8))
.andExpect(jsonPath("$",hasSize(0)));
assertFalse(studentDao.findById(1).isPresent());
}
@Test
public void 학생삭제예외처리_HttpRequest() throws Exception
{
assertFalse(studentDao.findById(0).isPresent());
mockMvc.perform(MockMvcRequestBuilders.delete("/student/{id}",0))
.andExpect(status().is4xxClientError())
.andExpect(jsonPath("$.status",is(404)))
.andExpect(jsonPath("$.message", is("Student or Grade was not found")));
}
@Test
public void studentInformationHttpRequest() throws Exception
{
Optional<CollegeStudent> student = studentDao.findById(1);
assertTrue(student.isPresent());
mockMvc.perform(MockMvcRequestBuilders.get("/studentInformation/{id}",1))
.andExpect(status().isOk())
.andExpect(content().contentType(APPLICATION_JSON_UTF8))
.andExpect(jsonPath("$.id",is(1)))
.andExpect(jsonPath("$.firstname",is("java")))
.andExpect(jsonPath("$.lastname",is("app")))
.andExpect(jsonPath("$.emailAddress",is("javapp@tistory.com")));
}
@Test
public void studentInformation_비어있음_HttpRequest() throws Exception
{
Optional<CollegeStudent> student = studentDao.findById(0);
assertFalse(student.isPresent());
mockMvc.perform(MockMvcRequestBuilders.get("/studentInformation/{id}",0))
.andExpect(status().is4xxClientError())
.andExpect(jsonPath("$.status",is(404)))
.andExpect(jsonPath("$.message",is("Student or Grade was not found")));
}
@Test
public void 유효한성적생성HttpRequest() throws Exception
{
this.mockMvc.perform(post("/grades")
.contentType(MediaType.APPLICATION_JSON)
.param("grade","85.00")
.param("gradeType","math")
.param("studentId","1"))
.andExpect(status().isOk())
.andExpect(content().contentType(APPLICATION_JSON_UTF8))
.andExpect(jsonPath("$.id",is(1)))
.andExpect(jsonPath("$.firstname",is("Eric")))
.andExpect(jsonPath("$.lastname",is("Roby")))
.andExpect(jsonPath("$.emailAddress",is("eric.roby@luv2code_school.com")))
.andExpect(jsonPath("$.studentGrades.mathGradeResults",hasSize(2)));
}
@Test
public void 유효한성적생성하는데_학생정보가없을때() throws Exception
{
this.mockMvc.perform(post("/grades")
.contentType(MediaType.APPLICATION_JSON)
.param("grade","85.00")
.param("gradeType","math")
.param("studentId", "0")
).andExpect(status().is4xxClientError())
.andExpect(jsonPath("$.status",is(404)))
.andExpect(jsonPath("$.message",is("Student or Grade was not found")));
}
@Test
public void 성적한개삭제HttpRequest() throws Exception
{
Optional<MathGrade> mathGrade = mathGradeDao.findById(1);
assertTrue(mathGrade.isPresent());
mockMvc.perform(MockMvcRequestBuilders.delete("/grades/{id}/{gradeType}",1,"math"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$.id",is(1)))
.andExpect(jsonPath("$.firstname",is("Eric")))
.andExpect(jsonPath("$.lastname",is("Roby")))
.andExpect(jsonPath("$.emailAddress",is("eric.roby@luv2code_school.com")))
.andExpect(jsonPath("$.studentGrades.mathGradeResults",hasSize(0)));
}
@Test
public void gradeType예외_유효하지않은성적삭제() throws Exception
{
mockMvc.perform(MockMvcRequestBuilders.delete("/grades/{id}/{gradeType}",2,"history"))
.andExpect(status().is4xxClientError())
.andExpect(jsonPath("$.status",is(404)))
.andExpect(jsonPath("$.message",is("Student or Grade was not found")));
mockMvc.perform(MockMvcRequestBuilders.delete("/grades/{id}/{gradeType}",1,"literature"))
.andExpect(status().is4xxClientError())
.andExpect(jsonPath("$.status",is(404)))
.andExpect(jsonPath("$.message",is("Student or Grade was not found")));
}
//
@AfterEach
public void setupAfterTransaction() {
jdbc.execute(sqlDeleteStudent);
jdbc.execute(sqlDeleteMathGrade);
jdbc.execute(sqlDeleteScienceGrade);
jdbc.execute(sqlDeleteHistoryGrade);
}
}
GET Test
@Test
public void getStudentHttpRequest() throws Exception
{
mockMvc.perform(MockMvcRequestBuilders.get("/"))
.andExpect(status().isOk())
.andExpect(content().contentType(APPLICATION_JSON_UTF8))
.andExpect(jsonPath("$",hasSize(1)));
}
POST Test
@Test
public void 유효한성적생성HttpRequest() throws Exception
{
this.mockMvc.perform(post("/grades")
.contentType(MediaType.APPLICATION_JSON)
.param("grade","85.00")
.param("gradeType","math")
.param("studentId","1"))
.andExpect(status().isOk())
.andExpect(content().contentType(APPLICATION_JSON_UTF8))
.andExpect(jsonPath("$.id",is(1)))
.andExpect(jsonPath("$.firstname",is("Eric")))
.andExpect(jsonPath("$.lastname",is("Roby")))
.andExpect(jsonPath("$.emailAddress",is("eric.roby@luv2code_school.com")))
.andExpect(jsonPath("$.studentGrades.mathGradeResults",hasSize(2)));
}
Delete Test
@Test
public void 성적한개삭제HttpRequest() throws Exception
{
Optional<MathGrade> mathGrade = mathGradeDao.findById(1);
assertTrue(mathGrade.isPresent());
mockMvc.perform(MockMvcRequestBuilders.delete("/grades/{id}/{gradeType}",1,"math"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$.id",is(1)))
.andExpect(jsonPath("$.firstname",is("Eric")))
.andExpect(jsonPath("$.lastname",is("Roby")))
.andExpect(jsonPath("$.emailAddress",is("eric.roby@luv2code_school.com")))
.andExpect(jsonPath("$.studentGrades.mathGradeResults",hasSize(0))); // 배열 검사
}
예외처리
@Test
public void 학생삭제예외처리_HttpRequest() throws Exception
{
assertFalse(studentDao.findById(0).isPresent());
mockMvc.perform(MockMvcRequestBuilders.delete("/student/{id}",0))
.andExpect(status().is4xxClientError())
.andExpect(jsonPath("$.status",is(404)))
.andExpect(jsonPath("$.message", is("Student or Grade was not found")));
}
appllication-test.properties
더보기
## H2 Test Database creds
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.datasource.initialization-mode=always
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql = true
## SQL Scripts
sql.script.create.student=insert into student(id,firstname,lastname,email_address) \
values (1,'Eric', 'Roby', 'eric.roby@luv2code_school.com')
sql.script.create.math.grade=insert into math_grade(id,student_id,grade) values (1,1,100.00)
sql.script.create.science.grade=insert into science_grade(id,student_id,grade) values (1,1,100.00)
sql.script.create.history.grade=insert into history_grade(id,student_id,grade) values (1,1,100.00)
sql.script.delete.student=DELETE FROM student
sql.script.delete.math.grade=DELETE FROM math_grade
sql.script.delete.science.grade=DELETE FROM science_grade
sql.script.delete.history.grade=DELETE FROM history_grade
'Back-end > 테스트' 카테고리의 다른 글
테스트와 테스트 주도 개발 TDD (0) | 2024.06.27 |
---|---|
Spring Boot MVC 서비스 테스트 (0) | 2022.11.09 |
Spring Boot MVC Controller Test (컨트롤러 테스트) (0) | 2022.11.05 |
Spring Boot MVC 데이터베이스 통합 테스트 @Sql (0) | 2022.10.29 |
Spring Boot Unit Testing - Mocking with Mockito - @MockBean, ReflectionTestUtils (0) | 2022.10.21 |
댓글