Spring Boot 유닛 테스트 와 통합 테스트 에 대한 상세 한 설명

본 튜 토리 얼 에서 제공 하 는 도 구 를 어떻게 사용 하 는 지 배우 고 Spring Boot 환경 에서 유닛 테스트 와 통합 테스트 를 작성 합 니 다.
1.개관
본 논문 에서 우 리 는 단원 테스트 를 어떻게 작성 하고 이 를Spring Boot환경 에 통합 하 는 지 알 게 될 것 이다.너 는 인터넷 에서 이 주제 에 관 한 많은 강 좌 를 찾 을 수 있 지만,한 페이지 에서 네가 필요 로 하 는 모든 정 보 를 찾기 는 매우 어렵다.나 는 초급 개발 자 들 이 유닛 테스트 와 통합 테스트 의 개념 을 헷 갈 리 게 하 는 것 을 자주 알 게 되 었 다.특히 Spring 생태 계 를 이야기 할 때.나 는 서로 다른 주해 가 서로 다른 문맥 에서 의 용법 을 분명하게 말 하려 고 시도 할 것 이다.
2.유닛 테스트 vs.통합 테스트
위 키 피 디 아 는 이렇게 말 했다유닛 테스트.
컴퓨터 프로 그래 밍 에서 유닛 테스트 는 소프트웨어 테스트 방법 으로 소스 코드 의 단일 유닛,하나 이상 의 컴퓨터 프로그램 모듈 의 집합 과 관련 된 제어 데이터,사용 과정 과 조작 과정 을 테스트 하여 사용 하기에 적합 한 지 확인한다.
통합 테스트
"통합 테스트(때로는 통합 과 테스트,줄 임 말 I&T)는 소프트웨어 테스트 의 한 단계 로 이 단계 에서 각 소프트웨어 모듈 이 조합 되 어 테스트 를 한다."
한 마디 로 하면 우리 가 유닛 테스트 를 할 때 하나의 코드 유닛 만 테스트 했 을 뿐 매번 하나의 방법 만 테스트 했 을 뿐 테스트 구성 요소 와 상호작용 을 하 는 다른 모든 구성 요 소 는 포함 되 지 않 았 다.
다른 한편,통합 테스트 에서 우 리 는 각 구성 요소 간 의 통합 을 테스트 합 니 다.유닛 테스트 로 인해 우 리 는 이 구성 요소 들 의 행동 이 필요 한 것 과 일치 하 는 것 을 알 수 있 지만 어떻게 함께 일 하 는 지 는 잘 모른다.이것 이 바로 통합 테스트 의 직책 이다.
3.자바 유닛 테스트
모든 자바 개발 자 들 은 JUnit 이 유닛 테스트 를 수행 하 는 주요 프레임 워 크 라 는 것 을 알 고 있 습 니 다.그것 은 기대 에 대해 단언 하기 위해 많은 주 해 를 제공 했다.
Hamcrest 는 소프트웨어 테스트 에 사용 되 는 추가 프레임 워 크 입 니 다.Hamcrest 는 기 존의 matcher 클래스 를 사용 하여 코드 의 조건 을 검사 할 수 있 고 사용자 정의 matcher 를 사용 할 수 있 습 니 다.JUnit 에서 Hamcrest matcher 를 사용 하려 면assertThat문 구 를 사용 해 야 합 니 다.그 다음 에 하나 이상 의 matcher 를 사용 해 야 합 니 다.
여기 서 당신 은 이 두 가지 프레임 워 크 를 사용 하 는 간단 한 테스트 를 볼 수 있 습 니 다.

import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.anyOf;
import static org.hamcrest.CoreMatchers.both;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.everyItem;
import static org.hamcrest.CoreMatchers.hasItems;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.sameInstance;
import static org.hamcrest.CoreMatchers.startsWith;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

import java.util.Arrays;

import org.hamcrest.core.CombinableMatcher;
import org.junit.Test;

public class AssertTests {
 @Test
 public void testAssertArrayEquals() {
  byte[] expected = "trial".getBytes();
  byte[] actual = "trial".getBytes();
  assertArrayEquals("failure - byte arrays not same", expected, actual);
 }

 @Test
 public void testAssertEquals() {
  assertEquals("failure - strings are not equal", "text", "text");
 }

 @Test
 public void testAssertFalse() {
  assertFalse("failure - should be false", false);
 }

 @Test
 public void testAssertNotNull() {
  assertNotNull("should not be null", new Object());
 }

 @Test
 public void testAssertNotSame() {
  assertNotSame("should not be same Object", new Object(), new Object());
 }

 @Test
 public void testAssertNull() {
  assertNull("should be null", null);
 }

 @Test
 public void testAssertSame() {
  Integer aNumber = Integer.valueOf(768);
  assertSame("should be same", aNumber, aNumber);
 }

 // JUnit Matchers assertThat
 @Test
 public void testAssertThatBothContainsString() {
  assertThat("albumen", both(containsString("a")).and(containsString("b")));
 }

 @Test
 public void testAssertThatHasItems() {
  assertThat(Arrays.asList("one", "two", "three"), hasItems("one", "three"));
 }

 @Test
 public void testAssertThatEveryItemContainsString() {
  assertThat(Arrays.asList(new String[] { "fun", "ban", "net" }), everyItem(containsString("n")));
 }

 // Core Hamcrest Matchers with assertThat
 @Test
 public void testAssertThatHamcrestCoreMatchers() {
  assertThat("good", allOf(equalTo("good"), startsWith("good")));
  assertThat("good", not(allOf(equalTo("bad"), equalTo("good"))));
  assertThat("good", anyOf(equalTo("bad"), equalTo("good")));
  assertThat(7, not(CombinableMatcher.<Integer> either(equalTo(3)).or(equalTo(4))));
  assertThat(new Object(), not(sameInstance(new Object())));
 }

 @Test
 public void testAssertTrue() {
  assertTrue("failure - should be true", true);
 }
}
4.우리 의 사례 소개
간단 한 프로그램 을 쓰 자.그 목적 은 만화 에 기본 적 인 검색엔진 을 제공 하 는 것 이다.
4.1.Maven 의존
우선 우리 프로젝트 에 의존 하 는 부분 을 추가 해 야 한다.

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-test</artifactId>
 <scope>test</scope>
</dependency>
<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
 <groupId>org.projectlombok</groupId>
 <artifactId>lombok</artifactId>
 <version>1.16.20</version>
 <scope>provided</scope>
</dependency>
4.2.정의 모델
우리 의 모델 은 매우 간단 하 다.단지 두 가지 유형 으로 구성 된다.그것 이 바로 Manga 와 MangaResult 이다.
4.2.1.만화 류
Manga 클래스 는 시스템 에서 검색 한 Manga 인 스 턴 스 를 표시 합 니 다.Lombok 을 사용 하여 모델 코드 를 줄 입 니 다.

package com.mgiglione.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter @Setter @NoArgsConstructor @AllArgsConstructor @Builder
public class Manga {
  private String title;
  private String description;
  private Integer volumes;
  private Double score;
}
4.2.2. MangaResult
Manga Result 류 는 Manga List 를 포함 한 포장 류 입 니 다.

package com.mgiglione.model;
import java.util.List;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter @Setter @NoArgsConstructor
public class MangaResult {
  private List<Manga> result;
}
4.3 서비스 실현
본 서 비 스 를 실현 하기 위해 저 희 는 Jikan Moe 가 제공 하 는 무료 API 인 터 페 이 스 를 사용 할 것 입 니 다.
RestTemplate 는 API 에 REST 호출 을 시작 하 는 Spring 클래스 입 니 다.

package com.mgiglione.service;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import com.mgiglione.model.Manga;
import com.mgiglione.model.MangaResult;

@Service
public class MangaService {

  Logger logger = LoggerFactory.getLogger(MangaService.class);
  private static final String MANGA_SEARCH_URL="http://api.jikan.moe/search/manga/";
  
  @Autowired
  RestTemplate restTemplate;
  
  public List<Manga> getMangasByTitle(String title) {
    return restTemplate.getForEntity(MANGA_SEARCH_URL+title, MangaResult.class).getBody().getResult();
  }
}
4.4.컨트롤 러 구현
다음 단 계 는 두 개의 단점 을 드 러 낸 REST Controller 를 쓰 는 것 입 니 다.하 나 는 동기 화 되 고 하 나 는 비동기 적 이 며 테스트 목적 에 만 사 용 됩 니 다.이 컨트롤 러 는 위 에서 정의 한 서 비 스 를 사용 했다.

package com.mgiglione.controller;

import java.util.List;
import java.util.concurrent.CompletableFuture;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.mgiglione.model.Manga;
import com.mgiglione.service.MangaService;

@RestController
@RequestMapping(value = "/manga")
public class MangaController {

  Logger logger = LoggerFactory.getLogger(MangaController.class);
  
  @Autowired
  private MangaService mangaService;  
  
  @RequestMapping(value = "/async/{title}", method = RequestMethod.GET)
  @Async
  public CompletableFuture<List<Manga>> searchASync(@PathVariable(name = "title") String title) {
    return CompletableFuture.completedFuture(mangaService.getMangasByTitle(title));
  }
  
  @RequestMapping(value = "/sync/{title}", method = RequestMethod.GET)
  public @ResponseBody <List<Manga>> searchSync(@PathVariable(name = "title") String title) {
    return mangaService.getMangasByTitle(title);
  }
}
4.5.시스템 시작 및 테스트

mvn spring-boot:run
그리고,Let's try it:

curl http://localhost:8080/manga/async/ken
curl http://localhost:8080/manga/sync/ken
예제 출력:

{ 
  "title":"Rurouni Kenshin: Meiji Kenkaku Romantan",
  "description":"Ten years have passed since the end of Bakumatsu, an era of war that saw the uprising of citizens against the Tokugawa shogunate. The revolutionaries wanted to create a time of peace, and a thriving c...",
  "volumes":28,
  "score":8.69
},
{ 
  "title":"Sun-Ken Rock",
  "description":"The story revolves around Ken, a man from an upper-class family that was orphaned young due to his family's involvement with the Yakuza; he became a high school delinquent known for fighting. The only...",
  "volumes":25,
  "score":8.12
},
{ 
  "title":"Yumekui Kenbun",
  "description":"For those who suffer nightmares, help awaits at the Ginseikan Tea House, where patrons can order much more than just Darjeeling. Hiruko is a special kind of a private investigator. He's a dream eater....",
  "volumes":9,
  "score":7.97
}
5.Spring Boot 응용 유닛 테스트
Spring Boot 는 테스트 를 간단하게 하기 위해 강력 한 종 류 를 제공 합 니 다.@SpringBootTest설명
Spring Boot 를 기반 으로 실행 되 는 테스트 클래스 에서 이 주 해 를 지정 할 수 있 습 니 다.
일반적인 Spring Test Context Framework 를 제외 하고 다음 과 같은 기능 도 제공 합 니 다.
  • @ContextConfiguration(loader=...)에 특별한 설명 이 없 을 때 SpringBootContextLoader 를 기본 ContextLoader 로 사용 합 니 다.
  • 끼 워 넣 은@Configuration 주 해 를 사용 하지 않 고 관련 클래스 가 명시 되 지 않 았 을 때@SpringBootConfiguration 을 자동 으로 검색 합 니 다.
  • Properties 를 사용 하여 Environment 속성 을 정의 할 수 있 습 니 다.
  • 정 의 된 포트 나 무 작위 포트 에서 완전히 실행 되 는 웹 서버 를 시작 하 는 기능 을 포함 하여 서로 다른 웹 환경 모델 을 지원 합 니 다.
  • TestRestTemplate 와/또는 WebTestClient Bean 을 등록 하여 웹 서버 에서 완전히 실행 되 는 웹 테스트 에서 사용 할 수 있 도록 합 니 다.
  • 이 곳 에서 저 희 는 두 개의 구성 요소 만 테스트 해 야 합 니 다:MangaService 와 MangaController
    5.1.MangaService 에 대해 유닛 테스트 를 실시한다.
    MangaService 를 테스트 하기 위해 서 는 외부 구성 요소 와 분리 해 야 합 니 다.이 예 에서 외부 구성 요소 만 필요 합 니 다:RestTemplate,원 격 API 를 호출 합 니 다.
    우리 가 해 야 할 일 은 RestTemplate Bean 을 모 의 하고 항상 고정된 응답 으로 응답 하도록 하 는 것 입 니 다.Spring Test 를 결합 하여 Mockito 라 이브 러 리 를 확장 하 였 습 니 다.@MockBean 주 해 를 통 해 아 날로 그 Bean 을 설정 할 수 있 습 니 다.
    
    package com.mgiglione.service.test.unit;
    import static org.mockito.ArgumentMatchers.any;
    import static org.mockito.Mockito.when;
    import java.io.IOException;
    import java.util.List;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.boot.test.mock.mockito.MockBean;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.test.context.junit4.SpringRunner;
    import org.springframework.web.client.RestTemplate;
    import static org.assertj.core.api.Assertions.assertThat;
    
    import com.mgiglione.model.Manga;
    import com.mgiglione.model.MangaResult;
    import com.mgiglione.service.MangaService;
    import com.mgiglione.utils.JsonUtils;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class MangaServiceUnitTest {
      
      @Autowired
      private MangaService mangaService;
      
      // MockBean is the annotation provided by Spring that wraps mockito one
      // Annotation that can be used to add mocks to a Spring ApplicationContext.
      // If any existing single bean of the same type defined in the context will be replaced by the mock, if no existing bean is defined a new one will be added.
      @MockBean
      private RestTemplate template;
      
      @Test
      public void testGetMangasByTitle() throws IOException {
        // Parsing mock file
        MangaResult mRs = JsonUtils.jsonFile2Object("ken.json", MangaResult.class);
        // Mocking remote service
        when(template.getForEntity(any(String.class), any(Class.class))).thenReturn(new ResponseEntity(mRs, HttpStatus.OK));
        // I search for goku but system will use mocked response containing only ken, so I can check that mock is used.
        List<Manga> mangasByTitle = mangaService.getMangasByTitle("goku");
        assertThat(mangasByTitle).isNotNull()
          .isNotEmpty()
          .allMatch(p -> p.getTitle()
            .toLowerCase()
            .contains("ken"));
      }
      
    }
    5.2.MangaController 에 대해 유닛 테스트 를 실시한다.
    MangaService 의 유닛 테스트 에서 보 듯 이 격 리 구성 요소 가 필요 합 니 다.이런 상황 에서 우 리 는 MangaService Bean 을 모 의 해 야 한다.
    그리고 또 하나의 문제 가 있 습 니 다.Controller 부분 은 HttpRequest 를 관리 하 는 시스템 의 일부분 이기 때문에 완전한 HTTP 서버 를 시작 하 는 것 이 아니 라 시스템 이 필요 합 니 다.
    MockMvc 는 이 동작 을 수행 하 는 Spring 클래스 입 니 다.다른 방식 으로 설정 할 수 있 습 니 다:
  • Standalone Context 사용
  • WebApplication Context 사용
  • Spring 은 테스트 클래스 에서@SpringBootTest,@AutoConfigure MockMvc 등 주 해 를 사용 하여 모든 컨 텍스트 를 불 러 와 자동 조립
  • 을 실현 하도록 합 니 다.
  • Spring 은 테스트 클래스 에서@WebMvcTest 주 해 를 사용 하여 웹 계층 의 컨 텍스트 를 불 러 와 자동 조립
  • 을 실현 하도록 합 니 다.
    
    package com.mgiglione.service.test.unit;
    
    import static org.hamcrest.Matchers.is;
    import static org.mockito.ArgumentMatchers.any;
    import static org.mockito.Mockito.when;
    import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch;
    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.jsonPath;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.request;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
    import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import org.junit.Before;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.boot.test.mock.mockito.MockBean;
    import org.springframework.http.MediaType;
    import org.springframework.test.context.junit4.SpringRunner;
    import org.springframework.test.web.servlet.MockMvc;
    import org.springframework.test.web.servlet.MvcResult;
    import org.springframework.web.context.WebApplicationContext;
    
    import com.mgiglione.controller.MangaController;
    import com.mgiglione.model.Manga;
    import com.mgiglione.service.MangaService;
    
    @SpringBootTest
    @RunWith(SpringRunner.class)
    public class MangaControllerUnitTest {
    
      MockMvc mockMvc;
      
      @Autowired
      protected WebApplicationContext wac;
      
      @Autowired
      MangaController mangaController;
      
      @MockBean
      MangaService mangaService;
      
      /**
       * List of samples mangas
       */
      private List<Manga> mangas;
      
      @Before
      public void setup() throws Exception {
        this.mockMvc = standaloneSetup(this.mangaController).build();// Standalone context
        // mockMvc = MockMvcBuilders.webAppContextSetup(wac)
        // .build();
        Manga manga1 = Manga.builder()
          .title("Hokuto no ken")
          .description("The year is 199X. The Earth has been devastated by nuclear war...")
          .build();
        Manga manga2 = Manga.builder()
          .title("Yumekui Kenbun")
          .description("For those who suffer nightmares, help awaits at the Ginseikan Tea House, where patrons can order much more than just Darjeeling. Hiruko is a special kind of a private investigator. He's a dream eater....")
          .build();
        mangas = new ArrayList<>();
        mangas.add(manga1);
        mangas.add(manga2);
      }
      
      @Test
      public void testSearchSync() throws Exception {
        // Mocking service
        when(mangaService.getMangasByTitle(any(String.class))).thenReturn(mangas);
        mockMvc.perform(get("/manga/sync/ken").contentType(MediaType.APPLICATION_JSON))
          .andExpect(status().isOk())
          .andExpect(jsonPath("$[0].title", is("Hokuto no ken")))
          .andExpect(jsonPath("$[1].title", is("Yumekui Kenbun")));
      }
    
      @Test
      public void testSearchASync() throws Exception {
        // Mocking service
        when(mangaService.getMangasByTitle(any(String.class))).thenReturn(mangas);
        MvcResult result = mockMvc.perform(get("/manga/async/ken").contentType(MediaType.APPLICATION_JSON))
          .andDo(print())
          .andExpect(request().asyncStarted())
          .andDo(print())
          // .andExpect(status().is2xxSuccessful()).andReturn();
          .andReturn();
        // result.getRequest().getAsyncContext().setTimeout(10000);
        mockMvc.perform(asyncDispatch(result))
          .andDo(print())
          .andExpect(status().isOk())
          .andExpect(jsonPath("$[0].title", is("Hokuto no ken")));
      }
    }
    코드 에서 보 듯 이 첫 번 째 해결 방안 을 선택 한 것 은 가장 가 벼 운 양 이 고 우 리 는 Spring 컨 텍스트 에 불 러 온 대상 을 더욱 잘 관리 할 수 있 기 때 문 입 니 다.
    비동기 테스트 에 서 는 먼저 서 비 스 를 호출 한 다음 에 asyncDispatch 방법 을 시작 하여 비동기 행 위 를 모 의 해 야 합 니 다.
    6.Spring Boot 응용 통합 테스트
    통합 테스트 에 대하 여 우 리 는 하위 통신 을 제공 하여 우리 의 주요 구성 요 소 를 검사 하 기 를 희망 합 니 다.
    6.1.MangaService 에 대한 통합 테스트
    이 테스트 도 매우 간단 하 다.우 리 는 원 격 Manga API 를 호출 하 는 것 이 목적 이기 때문에 어떤 것 도 모 의 할 필요 가 없다.
    
    package com.mgiglione.service.test.integration;
    
    import static org.assertj.core.api.Assertions.assertThat;
    
    import java.util.List;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    
    import com.mgiglione.model.Manga;
    import com.mgiglione.service.MangaService;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class MangaServiceIntegrationTest {
    
      @Autowired
      private MangaService mangaService;
      
      @Test
      public void testGetMangasByTitle() {
          List<Manga> mangasByTitle = mangaService.getMangasByTitle("ken");
          assertThat(mangasByTitle).isNotNull().isNotEmpty();
      }
    }
    6.2 MangaController 에 대한 통합 테스트
    이 테스트 는 단원 테스트 와 매우 비슷 하지만 이 사례 에서 우 리 는 MangaService 를 더 이상 모 의 할 필요 가 없다.
    
    package com.mgiglione.service.test.integration;
    import static org.hamcrest.Matchers.hasItem;
    import static org.hamcrest.Matchers.is;
    import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch;
    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.jsonPath;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.request;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
    import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
    
    import org.junit.Before;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.http.MediaType;
    import org.springframework.test.context.junit4.SpringRunner;
    import org.springframework.test.web.servlet.MockMvc;
    import org.springframework.test.web.servlet.MvcResult;
    import org.springframework.web.context.WebApplicationContext;
    
    import com.mgiglione.controller.MangaController;
    
    @SpringBootTest
    @RunWith(SpringRunner.class)
    public class MangaControllerIntegrationTest {
    
      // @Autowired
      MockMvc mockMvc;
      
      @Autowired
      protected WebApplicationContext wac;
      
      @Autowired
      MangaController mangaController;
      
      @Before
      public void setup() throws Exception {
        this.mockMvc = standaloneSetup(this.mangaController).build();// Standalone context
        // mockMvc = MockMvcBuilders.webAppContextSetup(wac)
        // .build();
      }
      
      @Test
      public void testSearchSync() throws Exception {
        mockMvc.perform(get("/manga/sync/ken").contentType(MediaType.APPLICATION_JSON))
          .andExpect(status().isOk())
          .andExpect(jsonPath("$.*.title", hasItem(is("Hokuto no Ken"))));
      }
      
      @Test
      public void testSearchASync() throws Exception {
        MvcResult result = mockMvc.perform(get("/manga/async/ken").contentType(MediaType.APPLICATION_JSON))
          .andDo(print())
          .andExpect(request().asyncStarted())
          .andDo(print())
          .andReturn();
        mockMvc.perform(asyncDispatch(result))
          .andDo(print())
          .andExpect(status().isOk())
          .andExpect(jsonPath("$.*.title", hasItem(is("Hokuto no Ken"))));
      }
    }
    7.결론
    Spring Boot 환경 에서 유닛 테스트 와 통합 테스트 의 주요 차이 점 을 알 고 Hamcrest 처럼 테스트 를 간소화 하 는 프레임 워 크 를 알 게 되 었 습 니 다.물론 내GitHub 창고에서 모든 코드 를 찾 을 수 있다.
    원문:https://dzone.com/articles/unit-and-integration-tests-in-spring-boot-2
    저자:Marco Giglione
    이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

    좋은 웹페이지 즐겨찾기