본문으로 바로가기
반응형

[스프링부트 (9)] SpringBoot Test(2) - @SpringBootTest로 통합테스트 하기

안녕하세요. 갓대희 입니다. 이번 포스팅은 [ 스프링 부트  통합 테스트 하기 (@SpringBootTest)입니다. : ) 

 

 

0. 들어가기 앞서

이번 포스팅의 대부분의 내용은 공식 레퍼런스 문서에 더 자세하게 나와 있다.

다음 공식 문서를 꼭 참고 하면 좋을 것 같다.
https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-testing

 

SpringBoot는 테스트 목적에 따라 다양한 어노테이션을 제공한다. 

 

☞  통합테스트

@SpringBootTest

 

단위테스트

@WebMvcTest, @DataJpaTest, @RestClientTest, @JsonTest 등등

 

이 중 오늘은 @SpringBootTest를 사용하여 아주 간단한 통합 테스트를 해보려 한다.

이를 위해 Spring Boot에서는 "spring-boot-starter-test"를 제공한다.
이전 포스팅에 이미 작성해 두었지만, "spring-boot-starter-test" 에는 다음 라이브러리들이 포함되어 있다.
 
 - JUnit 5 (including the vintage engine for backward compatibility with JUnit 4): The de-facto standard for unit testing Java applications.
 - Spring Test & Spring Boot Test: Utilities and integration test support for Spring Boot applications.
 - AssertJ: A fluent assertion library.
 - Hamcrest: A library of matcher objects (also known as constraints or predicates).
 - Mockito: A Java mocking framework.
 - JSONassert: An assertion library for JSON.
 - JsonPath: XPath for JSON.

 

스프링 이니셜라이져로 프로젝트를 생성한 경우 이미 "spring-boot-starter-test"가 디펜던시 추가되어 있을 것이다.

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-test</artifactId>
  <scope>test</scope>
  <exclusions>
    <exclusion>
      <groupId>org.junit.vintage</groupId>
      <artifactId>junit-vintage-engine</artifactId>
  	</exclusion>
  </exclusions>
</dependency>

해당 디펜던시 하나면 테스트 준비는 완료 된 상태이다.

 

1. 통합 테스트

▶ 1. 통합 테스트

1) 개요
 - 실제 운영 환경에서 사용될 클래스들을 통합하여 테스트 한다.
 - 단위 테스트와 같이 기능 검증을 위한 것이 아니라 spring framework에서 전체적으로 플로우가 제대로 동작하는지 검증하기 위해 사용 한다.
 
2) 장점
 - 애플리케이션의 설정, 모든 Bean을 모두 로드하기 때문에 운영환경과 가장 유사한 테스트가 가능하다.
 - 전체적인 Flow를 쉽게 테스트 가능하다.

3) 단점
 - 애플리케이션의 설정, 모든 Bean을 모두 로드하기 때문에 시간이 오래걸리고 무겁다.
 - 테스트 단위가 크기 때문에 디버깅이 어려운 편이다.

▶ @SpringBootTest

 - 스프링 부트는 @SpringBootTest 어노테이션을 통해 스프링부트 어플리케이션 테스트에 필요한 거의 모든 의존성을 제공한다.

 - @SpringBootTest는 통합 테스트를 제공하는 기본적인 스프링 부트 테스트 어노테이션 이다.

 - 해당 어노테이션을 사용시 Junit 버전에 따라 유의할 사항이 있다. (공식문서 참고)

 

If you are using JUnit 4, don’t forget to also add @RunWith(SpringRunner.class) to your test, otherwise the annotations will be ignored.
Junit4 사용시 @SpringBootTest 기능은 반드시 JUnit의 SpringJUnit4ClassRunner 클래스를 상속 받는 @RunWith(SpringRynnver.class)와 함께 사용해야 한다.
 
If you are using JUnit 5, there’s no need to add the equivalent @ExtendWith(SpringExtension.class) as @SpringBootTest 
and the other @…Test annotations are already annotated with it.
 Junit5 사용시에는 해당 어노테이션은 명시할 필요없다.

 

① properties

1.1) 프로퍼티를 {key=value} 형식으로 직접 추가할 수 있다.

//@RunWith(SpringRunner.class) => Junit4 사용시 추가, Junit5 사용시 생략.
@SpringBootTest(
	properties = {
		"propertyTest.value=propertyTest",
		"testValue=test"
	}
)
// ... 중략
@Value("${propertyTest.value}")
private String propertyTestValue; //propertyTest

@Value("${testValue}")
private String value; //test

1.2)  기본적으로 클래스 경로상의 application.properties(또는 application.yml)를 통해 애플리케이션 설정을 수행 한다.
 하지만 테스트를 위한 다른 설정이 필요하다면 다른 프로퍼티를 로드할 수 있다.

//@RunWith(SpringRunner.class) => Junit4 사용시 추가, Junit5 사용시 생략.
@SpringBootTest(
	properties = {"spring.config.location=classpath:application-test.properties"}
)

 

③ webEnvironment 

 - 웹 테스트 환경 구성이 가능하다.
 - webEnvironment 파라미터를 이용하여 손쉽게 웹 테스트 환경을 선택할 수 있다.

 

3.1) Mock
 - 실제 객체를 만들기엔 비용과 시간이 많이 들거나 의존성이 길게 걸쳐져 있어 제대로 구현하기 어려울 경우, 가짜 객체를 만들어 사용한다.
 - WebApplicationContext를 로드하며 내장된 서블릿 컨테이너가 아닌 Mock 서블릿을 제공한다.
 - 별도로 지정하지 않으면 기본값은 Mock 서블릿을 로드하여 구동하게 된다.
 - @AutoConfigureMockMvc 어노테이션을 함께 사용하면 별다른 설정 없이 간편하게 MockMvc를 사용한 테스트를 진행할 수 있다.
   MockMvc는 브라우저에서 요청과 응답을 의미하는 객체로서 Controller 테스테 사용을 용이하게 해주는 라이브러리이다.

※ @AutoConfigureMockMvc
 - Mock 테스트시 필요한 의존성을 제공해준다.
 - MockMvc 객체를 통해 실제 컨테이너가 실행되는 것은 아니지만 로직상으로 테스트를 진행할 수 있습니다. (DispatcherServlet을 로딩학여 Mockup으로 처리 가능)
 - print() 함수를 통해 좀 더 디테일한 테스트 결과를 볼 수 있다.

@Autowired 
MockMvc mvc;


3.2) RANDOM_PORT
 - EmbeddedWebApplicationContext를 로드하며 실제 서블릿 환경을 구성 한다.

 - 임의의 port listen


3.3) DEFINED_PORT
 - RAMDOM_PORT와 동일하게 실제 서블릿 환경을 구성하지만, 포트는 애플리케이션 프로퍼티에서 지정한 포트를 listen 한다.


3.4) NONE
 - 기본적인 ApplicationContext를 로드한다.


3.5) TestRestTemplate
 - webEnvironment설정시(NONE을 설정시 사용 불가) 그에 맞춰서 자동으로 설정되어 빈이 생성되며, RestTemplate의 테스트를 처리가 가능하다.

- Spring 4.x 이후부터 지원하는 Spring의 HTTP 통신 템플릿
- HTTP 요청 후 Json, xml, String 과 같은 응답을 받을 수 있는 템플릿
- Http request를 지원하는 HttpClient를 사용함
- ResponseEntity와 Server to Server 통신하는데 자주 쓰인다.
  (ResponseEntity는 응답 처리시 값 뿐만 아니라 상태코드, 응답메세지 등을 포함하여 리턴 가능하다. HttpEntity를 상속받기 떄문에 HttpHeader와 body를 가질수 있다.)
- Header, Content-Type등을 설정하여 외부 API 호출

@Autowired 
private TestRestTemplate restTemplate;

 

▶ @MockBean

 - Mock 객체를 빈으로써 등록할 수 있다.
 - @MockBean은 Spring의 ApplicationContext는 Mock 객체를 빈으로 등록하며, 혹시 @MockBean으로 선언된 객체와 같은 이름과 타입으로 이미 빈이 등록되어있다면 해당빈은 선언한 @MockBean으로 대체된다.

@MockBean
private MemberMapper memberMapper;

▶ @Transactional

 - 테스트 완료 후 자동으로 rollback 처리 한다.
   (spring-boot-test는 단순히 spring-test를 확장한 것이기 때문에 @Test 어노테이션과 함께 @Transactional 어노테이션을 함께 사용하면 테스트가 끝날 때 rollback 처리)
 - 하지만 WebEnvironment.RANDOM_PORT, DEFINED_PORT를 사용하면 실제 테스트 서버는 별도의 스레드에서 테스트를 수행하기 떄문에 트랜잭션이 롤백되지 않는다.

▶ @ActiveProfiles

 - 프로파일 전략을 사용 중이라면 원하는 프로파일 환경값 설정이 가능 하다.

 

 

▶ 실습 (test)

이제부터 예제를 통해 실행 해보고 해당 위의 내용들을 확인해 보자.

스프링부트 버전 : (SpringBoot 2.2.2 V)

 

이전 포스팅에서 JPA를 통해 CRUD를 했었는데, 해당 소스를 기반으로 테스트 하였다.

https://goddaehee.tistory.com/209

 

테스트 하였던 전체 소스는 다음과 같다. 이 전체 소스를 하나 하나 분리해서 간단히 설명 해보려 한다.

package com.god.bo.jpaTest.controller;

import com.god.bo.jpaTest.service.MemberService;
import com.god.bo.jpaTest.vo.MemberVo;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;

import javax.transaction.Transactional;
import java.util.Optional;

import static org.assertj.core.api.BDDAssertions.then;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.iterableWithSize;
import static org.hamcrest.core.Is.is;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

//@RunWith(SpringRunner.class) // ※ Junit4 사용시
@SpringBootTest(
        properties = {
                "testId=goddaehee2",
                "testName=갓대희"
        }
        //classes = {TestJpaRestController.class, MemberService.class},
        ,webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
)
@Transactional
@AutoConfigureMockMvc
@Slf4j
public class TestJpaRestControllerTest {

    @Value("${testId}")
    private String testId;

    @Value("${testName}")
    private String testName;
    
    /*@MockBean
    private MemberRepository memberRepository;*/

    @Autowired
    MockMvc mvc;

    @Autowired
    private TestRestTemplate restTemplate;

    // Service로 등록하는 빈
    @Autowired
    private MemberService memberService;

    @Autowired
    private WebApplicationContext ctx;

    @BeforeEach() //Junit4의 @Before
    public void setup() {
        this.mvc = MockMvcBuilders.webAppContextSetup(ctx)
                .addFilters(new CharacterEncodingFilter("UTF-8", true))  // 필터 추가
                .alwaysDo(print())
                .build();
    }

    @Test
    void getMember() throws Exception {
        log.info("##### Properties 테스트 #####");

        /******** START : MOC MVC test **********/
        log.info("******** START : MOC MVC test **********");
        mvc.perform(get("/memberTest/1"))
                .andExpect(status().isOk())
                .andExpect(content().contentType(MediaType.APPLICATION_JSON))
                .andExpect(jsonPath("$.id", is("goddaehee")))
                .andDo(print());
        log.info("******** END : MOC MVC test **********");
        /******** END : MOC MVC test **********/

        /******** START : TestRestTemplate test **********/
        log.info("******** START : TestRestTemplate test **********");
        ResponseEntity<MemberVo> response = restTemplate.getForEntity("/memberTest/1", MemberVo.class);
        then(response.getStatusCode()).isEqualTo(HttpStatus.OK);
        then(response.getBody()).isNotNull();
        log.info("******** END : TestRestTemplate test **********");
        /******** END : TestRestTemplate test **********/

        /******** START : MockBean test **********/
        log.info("******** START : MockBean test **********");
        /*
        MemberVo memberVo = MemberVo.builder()
                .id(testId)
                .name(testName)
                .build();

        given(memberRepository.findById(1L))
                .willReturn(Optional.of(memberVo));*/

        Optional<MemberVo> member = memberService.findById(1L);
        if (member.isPresent()) {
            // ※ Junit4 사용시
            // assertThat(memberVo.getId()).isEqualTo(member.get().getId());
            // assertThat(memberVo.getName()).isEqualTo(member.get().getName());

            // Junit5 BDD 사용시
            then("goddaehee").isEqualTo(member.get().getId());
            then("갓대희").isEqualTo(member.get().getName());
        }
        log.info("******** END : MockBean test **********");
        /******** END : MockBean test **********/
    }
}

 

0) TestClass 생성

통합 테스트할 클래스에서 Alt + Enter 클릭 > 원하는 메소드 체크 > 확인 (Junit5로 테스트 예정)

mbrNo로 회원을 조회하는 getMember 메서드를 선택 하였다.

 

1) properties

직접 선언한 properties의 값들이 올바르게 호출되는지 확인해 보았다.

//@RunWith(SpringRunner.class) // ※ Junit4 사용시
@SpringBootTest(
        properties = {
                "testId=goddaehee",
                "testName=갓대희"
        }
)
@Transactional
@Slf4j
public class TestJpaRestControllerTest {

    @Value("${testId}")
    private String testId;

    @Value("${testName}")
    private String testName;

    @Test
    void getMember() throws Exception {
        log.info("##### Properties 테스트 #####");
        log.info("testId : " + testId);
        log.info("testName : " + testName);
    }
}
INFO  20-02-28 00:06:46[main] [TestJpaRestControllerTest:81] - ##### Properties 테스트 #####
INFO  20-02-28 00:06:46[main] [TestJpaRestControllerTest:82] - testId : goddaehee
INFO  20-02-28 00:06:46[main] [TestJpaRestControllerTest:83] - testName : 갓대희

 

2) moc mvc

//@RunWith(SpringRunner.class) // ※ Junit4 사용시
@SpringBootTest(
        properties = {
                "testId=goddaehee",
                "testName=갓대희"
        }
)
@Transactional
@AutoConfigureMockMvc
@Slf4j
public class TestJpaRestControllerTest {

    @Value("${testId}")
    private String testId;

    @Value("${testName}")
    private String testName;
    
    @Autowired
    MockMvc mvc;
    
    // Service로 등록하는 빈
    @Autowired
    private MemberService memberService;

    @Test
    void getMember() throws Exception {
        log.info("##### Properties 테스트 #####");
        log.info("testId : " + testId);
        log.info("testName : " + testName);
        
        /******** START : MOC MVC test **********/
        log.info("******** START : MOC MVC test **********");
        mvc.perform(get("/memberTest/1"))
                .andExpect(status().isOk())
                .andExpect(content().contentType(MediaType.APPLICATION_JSON))
                .andExpect(jsonPath("$.id", is("goddaehee")))
                .andDo(print());
        log.info("******** END : MOC MVC test **********");
        /******** END : MOC MVC test **********/
    }
}
INFO  20-02-28 00:16:14[main] [TestJpaRestControllerTest:74] - ******** START : MOC MVC test **********
MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /memberTest/1
       Parameters = {}
          Headers = []
             Body = null
    Session Attrs = {}

Handler:
             Type = com.god.bo.jpaTest.controller.TestJpaRestController
           Method = com.god.bo.jpaTest.controller.TestJpaRestController#getMember(Long)

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = [Content-Type:"application/json"]
     Content type = application/json
             Body = {"mbrNo":1,"id":"goddaehee","name":"갓대희"}
    Forwarded URL = null
   Redirected URL = null
          Cookies = []
INFO  20-02-28 00:16:14[main] [TestJpaRestControllerTest:80] - ******** END : MOC MVC test **********

소스에 작성한대로 Status : 200, application/json 형태로 리턴되어 테스트에는 통과 하였다. 다만 한글이 깨져있는 것을 볼 수 있다.

 

mokMvc 한글 깨짐 현상은 MockMvc를 설정할 때 CharacterEncodingFilter를 추가 하면 해결 할 수 있다. 다음을 추가해주자.

@Autowired
private WebApplicationContext ctx;

@BeforeEach() //Junit4의 @Before
public void setup() {
this.mvc = MockMvcBuilders.webAppContextSetup(ctx)
.addFilters(new CharacterEncodingFilter("UTF-8", true))  // 필터 추가
.alwaysDo(print())
.build();
}

 

그럼 UTF-8로 세팅되어 한글 출력도 올바르게 나온다.

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = [Content-Type:"application/json;charset=UTF-8"]
     Content type = application/json
             Body = {"mbrNo":1,"id":"goddaehee","name":"갓대희"}
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

 

3) TestRestTemplate

 - TestRestTemplate을 사용하기 위해선 webEnvironment을 설정 해주어야 한다.

 

ex) webEnvironment 추가 전

@Autowired
    private TestRestTemplate restTemplate;
org.springframework.beans.factory.UnsatisfiedDependencyException: 
Error creating bean with name 'com.god.bo.jpaTest.controller.TestJpaRestControllerTest': 
Unsatisfied dependency expressed through field 'restTemplate'; 
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No qualifying bean of type 'org.springframework.boot.test.web.client.TestRestTemplate' 
available: expected at least 1 bean which qualifies as autowire candidate. 
Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

 

ex) webEnvironment 추가 (RANDOM_PORT 추가)후 오류 발생하지 않음을 확인할 수 있다.

@SpringBootTest(
        properties = {
                "testId=goddaehee",
                "testName=갓대희"
        }
        ,webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
)

 

ex) TestRestTemplate 테스트 추가 하여 실행

//@RunWith(SpringRunner.class) // ※ Junit4 사용시
@SpringBootTest(
        webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
)
@Transactional
@AutoConfigureMockMvc
@Slf4j
public class TestJpaRestControllerTest {
    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    void getMember() throws Exception {
        /******** START : TestRestTemplate test **********/
        log.info("******** START : TestRestTemplate test **********");
        ResponseEntity<MemberVo> response = restTemplate.getForEntity("/memberTest/1", MemberVo.class);
        then(response.getStatusCode()).isEqualTo(HttpStatus.OK);
        then(response.getBody()).isNotNull();
        log.info("******** END : TestRestTemplate test **********");
        /******** END : TestRestTemplate test **********/
 	}
}

테스트가 정상적으로 종료됨을 확인할 수 있다.

 

4) @MockBean

 - MockBean으로 테스트 하기전에 기본적인 Junit Test를 먼저 예시로 들어 보려 한다.

//@RunWith(SpringRunner.class) // ※ Junit4 사용시
@SpringBootTest
@Transactional
@AutoConfigureMockMvc
@Slf4j
public class TestJpaRestControllerTest {
	// Service로 등록하는 빈
    @Autowired
    private MemberService memberService;

    @Test
    void getMember() throws Exception {
        /******** START : TestRestTemplate test **********/
        log.info("******** START : TestRestTemplate test **********");
        ResponseEntity<MemberVo> response = restTemplate.getForEntity("/memberTest/1", MemberVo.class);
        then(response.getStatusCode()).isEqualTo(HttpStatus.OK);
        then(response.getBody()).isNotNull();
        log.info("******** END : TestRestTemplate test **********");
        /******** END : TestRestTemplate test **********/
 	}
}
Hibernate: 
    select
        membervo0_.mbr_no as mbr_no1_0_0_,
        membervo0_.id as id2_0_0_,
        membervo0_.name as name3_0_0_ 
    from
        member membervo0_ 
    where
        membervo0_.mbr_no=?
DEBUG 20-02-28 02:00:58[main] [sqltiming:368] -  com.zaxxer.hikari.pool.ProxyPreparedStatement.executeQuery(ProxyPreparedStatement.java:52)
1. select membervo0_.mbr_no as mbr_no1_0_0_, membervo0_.id as id2_0_0_, membervo0_.name as name3_0_0_ from member membervo0_ where membervo0_.mbr_no=1
 {executed in 7 msec}

 

 

올바르게 테스트 통과(Test passed) 하였고, 나와 같은 경우는 Database 세팅도 다 완료 하였기 떄문에 DB로그도 올바르게 찍히는것을 볼 수 있다.

하지만 실제 테스트 환경에서 시간도 없고, 특정 상황을 가정하고자 한다면 @MockBean을 통해 목객체로 선언하여 테스팅도 가능하다.

그리고 또한 다음 포스팅에서 다룰 단위 테스트 진행시, 예를들어 @WebMvcTest같은 경우 통합테스트보다 매우 가볍게 테스팅이 가능하고, DB연결 테스트를 하는게 아니기 떄문에 사용하면 유용하다. 미리 예를들어 사용 방법을 알아보자.

 

상기 소스중 Optional member = memberService.findById(1L);

memberService.findById의 결과는 다음과 같다.

{"mbrNo":1,"id":"goddaehee","name":"갓대희"}

 

이때의 결과를 id:goddaehee2 로 변경하여 테스트 해보는 예제이다

ex)

//@RunWith(SpringRunner.class) // ※ Junit4 사용시
@SpringBootTest
@Transactional
@AutoConfigureMockMvc
@Slf4j
public class TestJpaRestControllerTest {
    @MockBean
    private MemberRepository memberRepository;
	// Service로 등록하는 빈
    @Autowired
    private MemberService memberService;

    @Test
    void getMember() throws Exception {
        /******** START : MockBean test **********/
        log.info("******** START : MockBean test **********");
        MemberVo memberVo = MemberVo.builder()
                .id("goddaehee2")
                .name("갓대희")
                .build();

        given(memberRepository.findById(1L))
                .willReturn(Optional.of(memberVo));

		Optional<MemberVo> member = memberService.findById(1L);
        if (member.isPresent()) {
            // ※ Junit4 사용시
            // assertThat(memberVo.getId()).isEqualTo(member.get().getId());
            // assertThat(memberVo.getName()).isEqualTo(member.get().getName());

            // Junit5 BDD 사용시
            then("goddaehee").isEqualTo(member.get().getId());
            then("갓대희").isEqualTo(member.get().getName());
        }
        log.info("******** END : MockBean test **********");
        /******** END : MockBean test **********/
 	}
}
Expecting:
 <"goddaehee">
to be equal to:
 <"goddaehee2">
but was not., mergedContextConfiguration = [WebMergedContextConfiguration@18271936 testClass = TestJpaRestControllerTest, locations = '{}', classes = '{class com.god.bo.BoApplication}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{testId=goddaehee2, testName=갓대희, org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true, server.port=0}', contextCustomizers = set[[ImportsContextCustomizer@606e4010 key = [org.springframework.boot.test.autoconfigure.web.servlet.MockMvcAutoConfiguration, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcWebClientAutoConfiguration, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcWebDriverAutoConfiguration, org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration, org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcSecurityConfiguration]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@4466af20, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@3e58a80e, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@8687fa71, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@74fe5c40, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@4b3fa0b3, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@747ddf94], resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map['org.springframework.test.context.web.ServletTestExecutionListener.activateListener' -> false]]

에러가 발생 하였다.

실제 DB에는 "goddaehee2"가 들어가 있지만 @MockBean을 통해 가짜객체를 만들어 DB쿼리를 호출하지 않고 예상하는 값으로 설정하여 좀더 간단하게 다양한 경우를 가정하여 테스트 가능하다. 

 

다음 포스팅에선 단위 테스트 기능들도 알아보도록 하자.

반응형

댓글을 달아 주세요

  1. 음냐옹 2021.04.20 14:48

    안녕하세요. 블로그 잘 보고 있습니다. intellij에서 @Slf4j symbol: variable log can not find symbol 오류가 뜨던데 이거 혹시 방법을 알수 있을까요? 플러그인 깔았고 그래들은 써주신대로 되어있고.. annotation processing도 체크했습니다.