본문 바로가기

Springboot

[Springboot-error] 테스트코드 404에러

테스트코드를 작성하던 도중 다음과 같은 에러가 났다.

 

에러메시지

java.lang.AssertionError: Status 
Expected :200
Actual   :404

 

 

404가 발생한 이유는 생성한 컨트롤러 클래스에 아무것도 작성하지 않았기 때문에 매핑 요청이 왔을 때 404가 발생한 것이다. 그래서 컨트롤러 코드를 살펴보니 오타가 있었고 고치고 다시 실행하니 정상작동하였다.

 

// HelloController.java

package com.eunyeong.book.springboot.web;

import com.eunyeong.book.springboot.web.dto.HelloResponseDto;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestParam;

@RestController // 컨트롤러를 JSON을 반환하는 컨트롤러로 변환
public class HelloController { // GET의 요청을 받을 수 있는 API 생성

    @GetMapping("/hello")
    public String hello(){
        return "hello";
    } // /hello로 요청이 들어오면 문자열 hello를 반환

    @GetMapping("/hello/dto") //오타가 있었던 부분
    public HelloResponseDto helloDto(@RequestParam("name") String name,
                                     @RequestParam("amount") int amount){
        //RequestParam: 외부에서 API로 넘긴 파라미터를 가져오는 어노테이션
        return new HelloResponseDto(name, amount);
    }
}

 @GetMapping("/hello/dto") //오타가 있었던 부분

컨트롤러 코드를 살펴보면 이 부분에 오타가 있었다.

 

// HelloControllerTest.java

package com.eunyeong.book.springboot;

import com.eunyeong.book.springboot.web.HelloController;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;

import static org.hamcrest.Matchers.is;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@RunWith(SpringRunner.class) // 테스트 진행 시 SpringRunner라는 실행자 실행(스프링 부트 테스트와 JUnit 사이에 연결자 역할)
@WebMvcTest(controllers = HelloController.class,
        excludeFilters = {
        @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = SecurityConfig.class)
}) //Web에 집중할 수 있는 어노테이션
public class HelloControllerTest {

    @Autowired // 스프링이 관리하는 빈(bean)을 주입받음
    private MockMvc mvc; // 웹 API를 테스트할 때 사용, 스프링 MVC 테스트의 시작점

    @WithMockUser(roles="USER")
    @Test
    public void hello가_리턴된다() throws Exception{
        String hello = "hello";

        mvc.perform(get("/hello")) // /hello 주소로 HTTP GET 요청
                .andExpect(status().isOk()) // 결과 검증 - HTTP Header의 Status 검증(200인지 아닌지 검증)
                .andExpect(content().string(hello)); // 결과 검증 - 응답 본문의 내용 검증(Controller에서 "hello"를 리턴하기 때문에 이 값이 맞는지 검증)
    }

    @WithMockUser(roles="USER")
    @Test
    public void helloDto가_리턴된다() throws Exception {
        String name = "hello";
        int amount = 1000;

        mvc.perform(
                get("/hello/dto")
                        .param("name", name) // API 테스트할 때 사용될 요청 파라미터를 설정한다.
                        .param("amount", String.valueOf(amount)))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.name", is(name))) // JSON 응답값을 필드별로 검증할 수 있는 메소드
                .andExpect(jsonPath("$.amount", is(amount)));

    }
}

helloDto가_리턴된다() 코드를 실행하니 정상작동된 것을 볼 수 있었다.