Test

yshjft·2022년 5월 22일
0

@SpringBootTest

  • 테스트 코드를 위한 어노테이션
  • ApplicationContext에 모든 Bean들을 등록한다.

@AutoConfigureMockMvc

  • 컨트롤러 테스트 시 서블릿 컨테이너를 모킹하기 위해서 사용한다.

@SpringBootTest + @AutoConfigureMockMvc

  • @SpringBootTest에서 MockMvc를 주입하여 사용하기 위해서는 @AutoConfigureMockMvc 어노테이션을 붙여주어야 한다. 

    @SpringBootTest
    @AutoConfigureMockMvc // MockMvc를 생성한다.
    public class exmapleTest {
        @Autowired
        MockMvc mockMvc; // 생성된 MockMvc 빈을 주입받아 테스트에 사용한다.
    
        …
    }

@SpringBootTest의 WebEnvironment

  • WebEnvironment.Mock (기본값)

    • 실제 서블릿 컨데이너를 뛰우지 않고 Mocking된 서블릿 컨테이너가 생성된다.
  • WebEnvironment.RANDOM_PORT

    • 랜덤 포트로 내장 톰캣이 구동된다.
  • WebEnvironment.DEFINED_PORT

    • 정의된 포트로 내장 톰캣이 구동된다.
  • WebEnvironment.NONE

    • 서블릿 환경을 제공하지 않고 ApplicationContext만 로드한다.

@DataJpaTest

  • 테스트 코드를 위한 어노테이션
  • JPA 관련하여 필요한 것들만 빈으로 등록한다.
  • @Transactional을 명시하지 않아도 알아서 롤백된다. 정확히는 @DataJpaTest의 내부를 까보면 이미 @Transactional을 포함하고 있다.
    • Insert query가 전달되지 않는다.
  • In-memory DB를 활용해서 테스트가 실행된다.(h2)

@WebMvcTest

  • 웹과 관련된 것들만 빈으록 등록(controller...등, service & repository는 사용될 수 없습니다.)
    • 가볍게 테스트 할 수 있다는 장점이 존재한다.
  • 컨트롤러를 테스트하는데 적합하다.
    • web레이어 관련 빈들만 등록되고 service는 등록되지 않으므로 온전한 테스트를 위해 @MockBean을 이용해 service관련 빈들을 가짜로 만들어 등록해야한다.
  • 예시)
@WebMvcTest(SampleController.class)
public class SampleControllerTest extends TestCase {
	@MockBean
	SampleService mockSampleService;

	@Autowired
	MockMvc mockMvc;

	@Test
	public void hello() throws Exception {
	    when(mockSampleService.getName()).thenReturn("jerry");

    	mockMvc.perform(get("/hello"))
        	    .andExpect(content().string("hello jerry"));

	}
}

@Nested

테스트 코드에서 @Nested 클래스로 비슷한 함수를 묶어 가독성을 좋게 만든다.

Before

public class ExampleTest {

    @Test
    public void testAsuccess() { ... }

    @Test
    public void testAfail() { ... }

    @Test
    public void test1success() { ...  }

    @Test
    public void test1success() { ... }

    @Test
    public void test2success() { ... }

    @Test
    public void test2fail() { ... }
}

After

public class ExampleTest {
    @Nested
    class testA {
        @Test
        public void success() { ... }

        @Test
        public void fail() { ... }
    }

    @Nested
    class testNumber {
        @Nested
        class test1 {
            @Test
            public void success() { ... }

            @Test
            public void fail() { ... }
        }

        @Nested
        class test2 {
            @Test
            public void success() { ... }

            @Test
            public void fail() { ... }

        }
    }
}

MockMvc

  • 실제 객체와 비슷하지만 테스트에 필요한 기능만 가지는 가짜 객체를 만들어서 애플리케이션 서버에 배포하지 않고도 스프링 MVC 동작을 재현할 수 있는 클래스이다.
    • 어플리케이션을 서버에 배포하지 않고 테스트용 MVC환경을 만들어 요청 및 전송, 응답기능을 제공한다.

Mockito의 어노테이션

@Mock

  • 행위 조작이 가능한 형태만 같은 껍데기 mock객체를 생성한다.
  • @ExtendWith(MockitoExtension.class) 사용 필수!

@Spy

  • 객체를 선택적으로 stub할 수 있다.
  • @Spy로 만든 mock 객체는 진짜 객체이며 메소드 실행 시 스터빙을 하지 않으면 기존 객체의 로직을 실행한 값을, 스터빙을 한 경우엔 스터빙 값을 리턴한다.

@MockBean

  • MockBean은 기존에 사용되던 Bean의 껍데기만 가져오고 내부의 구현 부분은 모두 사용자에게 위임한 형태이다.
  • 스프링 컨텍스트에 mock객체를 등록하게 되고 스프링 컨텍스트에 의해 @Autowired가 동작할 때 등록된 mock객체를 사용할 수 있도록 동작한다.
  • Mock 객체들을 ApplicationContext에 넣어주고 만약 동일한 타입의 Bean이 존재할 경우 MockBean으로 교체해준다.
  • 테스트에 Spring Container가 필요하고 Bean container에 존재 해야 하는 경우사용한다.
  • @SpringBootTest와 @WebMvcTest에서 사용된다.
    • @SpringBootTest + @MockBean
    • @WebMvcTest + @MockBean

@InjectMocks

  • @Mock이나 @Spy로 생성된 mock 객체를 자동으로 주입해준다.
  • @Mock or @Spy + @InjectMocks
profile
꾸준히 나아가자 🐢

0개의 댓글