본문 바로가기
Back-end/테스트

Spring Boot Rest APIs Test

by javapp 자바앱 2022. 11. 14.
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

댓글