SpringBoot 프로젝트 에서 Mockito 의 예제 코드 를 사용 합 니 다.

9636 단어 SpringBootMockito
Spring Boot 는 대부분의 유행 하 는 테스트 프레임 워 크 와 협동 작업 을 할 수 있 습 니 다.Spring JUnit 을 통 해 유닛 테스트 를 만 들 수 있 습 니 다.테스트 데이터 초기 화 데이터 베 이 스 를 생 성하 여 테스트 에 사용 하기;Spring Boot 는 BDD(Behavier Driven Development)도구,Cucumber,Spock 과 협동 하여 응용 프로그램 을 테스트 할 수 있다.
소프트웨어 개발 을 할 때 우 리 는 많은 코드 를 쓸 것 입 니 다.그러나 6 개 월 만 지나 면(심지어 1 년 이상)자신의 코드 가 어떻게 작 동 하 는 지 아 십 니까?테스트(유닛 테스트,통합 테스트,인터페이스 테스트)를 통 해 시스템 의 유지 가능성 을 확보 할 수 있 습 니 다.일부 코드 를 수정 할 때 회귀 테스트 를 통 해 새로운 bug 가 도입 되 었 는 지 확인 할 수 있 습 니 다.어쨌든 테스트 는 시스템 이 더 이상 블랙박스 가 아니 라 개발 자 들 로 하여 금 시스템 이 사용 가능 하 다 는 것 을 확인 하 게 해 야 한다.
웹 응용 프로그램 에서 컨트롤 러 층 에 대한 테스트 는 일반적으로 두 가지 방법 이 있 습 니 다.(1)http 요청 을 보 냅 니 다.(2)http 요청 대상 을 모 의 한다.첫 번 째 방법 은 회귀 환경 을 설정 하고 코드 통 계 를 수정 하 는 전략 을 통 해 도달 율 을 계산 해 야 한다.두 번 째 방법 은 비교적 정규 적 인 사고 이지 만 제 가 현재 겪 은 프로젝트 에서 많이 사용 하지 않 았 습 니 다.오늘 은 Mock 대상 으로 Controller 층 의 코드 를 어떻게 테스트 하 는 지 정리 하 겠 습 니 다.
이전 몇 편의 글 에서 저 희 는 모두 bookpub 이라는 프로그램 을 예 로 들 었 습 니 다.오늘 도 예 외 는 아 닙 니 다.제 공 된 RESTful 인터페이스 가 정확 한 응답 데 이 터 를 되 돌 릴 수 있 는 지 테스트 하려 고 합 니 다.이러한 테스트 는 유닛 테스트 와 달리 완전한 응용 프로그램 컨 텍스트 를 초기 화하 고 모든 spring bean 을 짜 고 데이터 베이스 에 테스트 데이터 가 필요 합 니 다.일반적으로 이러한 테스트 를 통합 테스트 나 인터페이스 테스트 라 고 합 니 다.
실전
spirng.io 를 통 해 새로 만 든 Spring Boot 프로젝트 는 빈 테스트 파일 인 BookPubApplicationTest.java 를 제공 합 니 다.내용 은:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = BookPubApplication.class)
public class BookPubApplicationTests {
  @Test
  public void contextLoads() {
  }
}
pom 파일 에 spring-boot-starter-test 의존 도 를 증가 시 키 고 jsonPath 의존 도 를 추가 합 니 다.

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-test</artifactId>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>com.jayway.jsonpath</groupId>
  <artifactId>json-path</artifactId>
</dependency>
BookPubApplicationTest 에 테스트 용례 를 추가 합 니 다.

package com.test.bookpub;

import com.test.bookpub.domain.Book;
import com.test.bookpub.repository.BookRepository;
import org.junit.Before;import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.TestRestTemplate;
import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.WebApplicationContext;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.hamcrest.Matchers.containsString;
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(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = BookPubApplication.class)
@WebIntegrationTest("server.port:0")
public class BookPubApplicationTests {
  @Autowired
  private WebApplicationContext context;
  @Autowired
  private BookRepository bookRepository;
  @Value("${local.server.port}")
  private int port;

  private MockMvc mockMvc;
  private RestTemplate restTemplate = new TestRestTemplate();

  @Before
  public void setupMockMvc() {
    mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
  }

  @Test
  public void contextLoads() {
    assertEquals(1, bookRepository.count());
  }

  @Test
  public void webappBookIsbnApi() {
    Book book = restTemplate.getForObject("http://localhost:" + port +"/books/9876-5432-1111", Book.class);
    assertNotNull(book);
    assertEquals("    ", book.getPublisher().getName());
  }

  @Test
  public void webappPublisherApi() throws Exception {
    //MockHttpServletRequestBuilder.accept                
    //MockHttpServletRequestBuilder.contentType,       Content-Type  ,          
    mockMvc.perform(get("/publishers/1")
        .accept(MediaType.APPLICATION_JSON_UTF8))

        .andExpect(status().isOk()) 
        .andExpect(content().string(containsString("    ")))
        .andExpect(jsonPath("$.name").value("    "));
  }
}

spring boot 프로젝트 의 코드 보급률
cobertura 를 사용 하여 프로젝트 의 github 주 소 를 참고 하 십시오spring boot template

# To create test coverage reports (in target/site/cobertura)
mvn clean cobertura:cobertura test


분석 하 다.
먼저 BookPubApplications Tests 클래스 에 사 용 된 주 해 를 분석 합 니 다.
  • @RunWith(SpringJUnit 4 ClassRunner.class),이것 은 JUnit 의 주해 입 니 다.이 주 해 를 통 해 SpringJUnit 4 ClassRunner 라 는 종 류 를 Spring 테스트 컨 텍스트 를 제공 합 니 다
  • @SpringApplicationConfiguration(classes=BookPubApplication.class)은 Spring Boot 주석 입 니 다.통합 테스트 를 위해 서 는 이 주석 을 통 해 Spring 응용 컨 텍스트 를 불 러 오고 설정 해 야 합 니 다.이것 은 메타 주석(meta-annoation)입 니 다.@ContextConfiguration(loader=SpringApplication ContextLoader.class)이라는 주 해 를 포함 하고 있 습 니 다.테스트 프레임 워 크 는 이 주 해 를 통 해 Spring Boot 프레임 워 크 를 사용 하 는 SpringApplication ContextLoader 로 더 를 통 해 응용 프로그램 상하 문 을 만 듭 니 다
  • @WebIntegrationTest("server.port:0")는 현재 테스트 가 통합 테스트(integration test)임 을 나타 내 므 로 완전한 컨 텍스트 를 초기 화하 고 응용 프로그램 을 시작 해 야 합 니 다.이 주 해 는 일반적으로@SpringApplication Configuration 과 함께 나타 납 니 다.server.port:0 은 Spring Boot 를 랜 덤 포트 에서 Tomcat 서 비 스 를 시작 하 게 한 다음 테스트 에서 프로그램 이@Value("${local.server.port}")를 통 해 이 포트 번 호 를 얻 고 port 변 수 를 할당 하 는 것 을 말 합 니 다.Jenkins 나 다른 지속 적 인 통합 서버 에서 테스트 프로그램 을 실행 할 때 이 무 작위 로 포트 를 가 져 오 는 능력 은 테스트 프로그램의 병행 성 을 제공 할 수 있 습 니 다
  • 테스트 류 의 주 해 를 알 고 테스트 류 의 내 부 를 살 펴 보 자.이것 은 Spring Boot 의 테스트 이기 때문에 저 희 는@Autowired 주 해 를 통 해 Spring 이 관리 하 는 대상 이나@Value 를 통 해 지정 한 환경 변 수 를 설정 할 수 있 습 니 다.현재 이 테스트 클래스 에서 우 리 는 웹 응용 프로그램 Context 와 BookRepository 대상 을 정의 합 니 다.
    모든 테스트 용례 는@Test 주해 로 수식 합 니 다.첫 번 째 테스트 사례 인 contextLoads()방법 에서 저 는 BookRepository 연결 이 이미 구축 되 었 고 데이터 베이스 에 해당 하 는 테스트 데 이 터 를 포함 하고 있 음 을 확인 해 야 합 니 다.
    두 번 째 테스트 용례 는 우리 가 제공 한 RESTful URL 을 테스트 하 는 데 사 용 됩 니 다.ISBN 을 통 해 책 한 권 을 조회 합 니 다.즉,"/books/{isbn}"입 니 다.이 테스트 용례 에서 우 리 는 TestRestTemplate 대상 을 사용 하여 RESTful 요청 을 합 니 다.
    세 번 째 테스트 사례 에 서 는 MockMvc 대상 을 통 해 두 번 째 테스트 와 유사 한 기능 을 실현 하 는 방법 을 보 여 주 었 다.Spring 테스트 프레임 워 크 는 MockMvc 대상 을 제공 합 니 다.클 라 이언 트-서버 요청 이 필요 없 이 MVC 테스트 를 할 수 있 습 니 다.서버 쪽 에서 Controller 요청 을 수행 할 수 있 습 니 다.테스트 서버 를 시작 한 것 과 같 습 니 다.
    테스트 가 시작 되 기 전에 테스트 환경 을 만들어 야 합 니 다.setup 방법 은@Before 에 의 해 수 정 됩 니 다.MockMvcBuilders 도 구 를 통 해 WebApplication Context 대상 을 매개 변수 로 하여 MockMvc 대상 을 만 듭 니 다.
    MockMvc 대상 은 assert 판단 을 수행 하 는 도구 함 수 를 제공 합 니 다.모두 웹 요청 에 대한 판단 입 니 다.이 도구 의 사용 방식 은 함수 의 체인 호출 입 니 다.프로그래머 가 여러 개의 테스트 용례 를 연결 하고 여러 개의 판단 을 할 수 있 도록 합 니 다.이 예 에서 우 리 는 아래 의 도구 함수 들 을 사용한다.
  • perform(get(...)웹 요청 을 만 듭 니 다.세 번 째 사례 에서 MockMvcRequestBuilder 를 통 해 GET 요청 을 수행 합 니 다
  • andExpect(...)는 perform(...)함수 호출 후 여러 번 호출 하여 여러 조건 에 대한 판단 을 나 타 낼 수 있 습 니 다.이 함수 의 매개 변수 유형 은 ResultMatcher 인터페이스 입 니 다.MockMvc ResultMatcher 와 같은 종류 에서 ResultMatcher 인 터 페 이 스 를 되 돌려 주 는 도구 함 수 를 많이 제공 합 니 다.이 함 수 는 HTTP 응답 상태 코드(response status),응답 하 는 콘 텐 츠 유형(content type),세 션 에 저 장 된 값,재 설정,model 또는 header 의 내용 등 을 포함 하여 같은 웹 요청 의 여러 가지 측면 을 감지 할 수 있 습 니 다.여 기 는 제3자 라 이브 러 리 json-path 를 통 해 JSON 형식의 응답 데 이 터 를 검 측 해 야 합 니 다.json 데이터 에 정확 한 요소 유형 과 대응 하 는 값 이 포함 되 어 있 는 지 확인 하 십시오.예 를 들 어 jsonPath("$.name").value("중국어 테스트")는 루트 디 렉 터 리 에 name 이라는 노드 가 있 는 지 확인 하고 이 노드 에 대응 하 는 값 은"중국어 테스트"입 니 다
  • 질문
    질문 설명:spring-boot-starter-data-rest 를 통 해 만 든 reposcory 에서 꺼 낸 한 자 는 어 지 러 운 코드 입 니 다
  • 분석:postman 과 httpie 인증 을 사용 해도 문제 가 없다.이 는 Mockmvc 의 테스트 사례 가 잘못 썼 다 는 것 을 의미한다.클 라 이언 트 가 HTTP 응답 을 어떻게 해석 하 는 지 주동 적 으로 설정 하고 get.accept 방법 으로 클 라 이언 트 가 식별 할 수 있 는 내용 유형 을 설정 해 야 한다.수 정 된 테스트 사례 는 다음 과 같다
  • 
    @Test
    public void webappPublisherApi() throws Exception {
      //MockHttpServletRequestBuilder.accept                
      //MockHttpServletRequestBuilder.contentType,       Content-Type  ,          
      mockMvc.perform(get("/publishers/1")
          .accept(MediaType.APPLICATION_JSON_UTF8))
    
          .andExpect(status().isOk())
          .andExpect(content().string(containsString("    ")))
          .andExpect(jsonPath("$.name").value("    "));
    }
    
    
    이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

    좋은 웹페이지 즐겨찾기