수색…


간단한 스프링 부트 애플리케이션을 테스트하는 방법

우리는 사용자 데이터를 MongoDB에 저장하는 샘플 스프링 부트 애플리케이션을 가지고 있으며 Rest 서비스를 사용하여 데이터를 검색합니다

먼저 POJO라는 도메인 클래스가 있습니다.

@Document
public class User{
    @Id
    private String id;

    private String name;

}

Spring Data MongoDB에 기반한 해당 저장소

public interface UserRepository extends MongoRepository<User, String> {
}

그런 다음 사용자 컨트롤러

@RestController
class UserController {
 
    @Autowired
    private UserRepository repository;
 
    @RequestMapping("/users")
    List<User> users() {
        return repository.findAll();
    }
 
    @RequestMapping(value = "/Users/{id}", method = RequestMethod.DELETE)
    @ResponseStatus(HttpStatus.NO_CONTENT)
    void delete(@PathVariable("id") String id) {
        repository.delete(id);
    }
 
    // more controller methods
}

마지막으로 스프링 부트 애플리케이션

@SpringBootApplication
public class Application {
    public static void main(String args[]){
     SpringApplication.run(Application.class, args);
    }
}

John Cena, The Rock 및 TripleHHH가 데이터베이스의 유일한 세 명의 사용자라고 가정하면 / users에 대한 요청은 다음과 같은 응답을 제공합니다.

$ curl localhost:8080/users
[{"name":"John Cena","id":"1"},{"name":"The Rock","id":"2"},{"name":"TripleHHH","id":"3"}]

이제 코드를 테스트하기 위해 애플리케이션이 작동하는지 확인합니다.

@RunWith(SpringJUnit4ClassRunner.class)   // 1
@SpringApplicationConfiguration(classes = Application.class)   // 2
@WebAppConfiguration   // 3
@IntegrationTest("server.port:0")   // 4
public class UserControllerTest {

    @Autowired   // 5
    UserRepository repository;

    User cena;
    User rock;
    User tripleHHH;

    @Value("${local.server.port}")   // 6
    int port;

    @Before
    public void setUp() {
        // 7
        cena = new User("John Cena");
        rock = new User("The Rock");
        tripleHHH = new User("TripleHH");

        // 8
        repository.deleteAll();
        repository.save(Arrays.asList(cena, rock, tripleHHH));

        // 9
        RestAssured.port = port;
    }

    // 10
    @Test
    public void testFetchCena() {
        String cenaId = cena.getId();

        when().
                get("/Users/{id}", cenaId).
        then().
                statusCode(HttpStatus.SC_OK).
                body("name", Matchers.is("John Cena")).
                body("id", Matchers.is(cenaId));
    }

    @Test
    public void testFetchAll() {
        when().
                get("/users").
        then().
                statusCode(HttpStatus.SC_OK).
                body("name", Matchers.hasItems("John Cena", "The Rock", "TripleHHH"));
    }

    @Test
    public void testDeletetripleHHH() {
        String tripleHHHId = tripleHHH.getId();

        when()
                .delete("/Users/{id}", tripleHHHId).
        then().
                statusCode(HttpStatus.SC_NO_CONTENT);
    }
}

설명

  1. 다른 Spring 기반 테스트와 마찬가지로 SpringJUnit4ClassRunner 가 필요하므로 애플리케이션 컨텍스트가 만들어집니다.
  2. @SpringApplicationConfiguration 주석은 테스트에서 사용해야하는 응용 프로그램 컨텍스트를 지정하는 데 사용된다는 점에서 @ContextConfiguration 주석과 유사합니다. 또한 Spring Boot 특정 구성, 속성 등을 읽는 논리를 트리거합니다.
  3. @WebAppConfigurationWebApplicationContext 가 테스트를 위해로드되어야한다는 것을 Spring에 알리기 위해 존재해야한다. 또한 웹 응용 프로그램의 루트에 대한 경로를 지정하는 속성을 제공합니다.
  4. @IntegrationTest 는 Spring Boot에게 임베디드 웹 서버가 시작되어야 함을 알려주는 데 사용됩니다. 콜론 또는 등호로 구분 된 이름 - 값 쌍을 제공하여 모든 환경 변수를 재정의 할 수 있습니다. 이 예제에서 "server.port:0" 은 서버의 기본 포트 설정보다 우선합니다. 일반적으로 서버는 지정된 포트 번호를 사용하기 시작하지만 값 0은 특별한 의미가 있습니다. 0으로 지정되면, Spring Boot는 호스트 환경의 포트를 스캔하여 사용 가능한 임의의 포트에서 서버를 시작하도록 지시합니다. 이는 응용 프로그램 포트와 충돌 할 가능성이있는 개발 컴퓨터와 빌드 서버에서 서로 다른 포트를 차지하는 다른 서비스가있는 경우에 유용합니다.이 경우 응용 프로그램이 시작되지 않습니다. 둘째, 서로 다른 응용 프로그램 컨텍스트를 사용하여 여러 통합 테스트를 만들면 테스트가 동시에 실행되는 경우 충돌이 발생할 수 있습니다.
  5. 우리는 애플리케이션 컨텍스트에 접근 할 수 있고 autowiring을 사용하여 Spring 빈을 주입 할 수있다.
  6. @Value("${local.server.port}”) 는 사용 된 실제 포트 번호로 확인됩니다.
  7. 유효성 검사에 사용할 수있는 엔티티를 만듭니다.
  8. MongoDB 데이터베이스는 지워지고 각 테스트에 대해 다시 초기화되므로 알려진 상태에 대해 항상 유효성을 검사합니다. 테스트 순서가 정의되지 않았으므로 testDeletetripleHHH () 테스트 후에 testFetchAll () 테스트가 실행되면 실패합니다.
  9. Rest Assured 가 올바른 포트를 사용하도록 지시합니다. 그것은 편안한 서비스를 테스트하기위한 Java DSL을 제공하는 오픈 소스 프로젝트입니다.
  10. 테스트는 Rest Assured를 사용하여 구현됩니다. 우리는 TestRestTemplate 또는 다른 http 클라이언트를 사용하여 테스트를 구현할 수 있지만 RestDocs를 사용하여 간결한 문서를 작성할 수 있으므로 Rest Assured를 사용 합니다.

다른 yaml [또는 특성] 파일로드 또는 일부 특성 대체

@SpringApplicationConfiguration 을 사용할 때 특정 상황에서는 적절하지 않은 application.yml [properties]의 구성을 사용합니다. 따라서 속성을 재정의하려면 @TestPropertySource 주석을 사용할 수 있습니다.

@TestPropertySource(
        properties = {
                "spring.jpa.hibernate.ddl-auto=create-drop",
                "liquibase.enabled=false"
        }
)
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(Application.class)
public class ApplicationTest{

    // ...

}

@TestPropertySource 속성 속성을 사용하여 원하는 특정 속성 을 무시할 수 있습니다. 위의 예제에서 우리는 create-drop spring.jpa.hibernate.ddl-auto 속성을 오버라이드 합니다. 그리고 liquibase.enabledfalse .

다른 yml 파일로드 중

테스트를 위해 다른 yml 파일을 완전히로드하려면 @TestPropertySource 위치 특성을 사용할 수 있습니다.

@TestPropertySource(locations="classpath:test.yml")
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(Application.class)
public class ApplicationTest{

    // ...

}

다른 옵션

옵션 1:

또한 다른 yml 파일을로드하여 yml 파일을 test > resource 디렉토리에 배치 할 수 있습니다.

옵션 2 :

@ActiveProfiles 주석 사용

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@ActiveProfiles("somename")
public class MyIntTest{
}

@ActiveProfiles 주석을 사용하는 것을 볼 수 있으며 값으로 somename 을 전달합니다.

application-somename.yml 이라는 파일을 만들고 테스트가이 파일을로드합니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow