Как выполнить модульное тестирование API-интерфейса Jersey REST без запуска сервера? - PullRequest
0 голосов
/ 28 августа 2018

Я работаю с REST API, использующим Джерси с Spring Boot (поэтому нет конкретного контекста приложения в XML или Java) и Spring Data JPA.

Я хочу написать модульные тесты на конечных точках GET и POST, однако я не хочу запускать веб-сервер, так как это занимает слишком много времени.

Если я использую JerseyTest, мои Spring Beans не загружаются в контекст.

public class InMemoryContainerPackageTest extends 
        JerseyTestNg.ContainerPerClassTest {

  @Override
  protected TestContainerFactory getTestContainerFactory() {
    return new InMemoryTestContainerFactory();
  }

  @Override
  public Application configure() {
    ResourceConfig config = new ResourceConfig()
                              .register(SpringLifecycleListener.class)
                              .register(RequestContextFilter.class)
                              .register(this)
                              .register(MyController.class)
                              .packages("com.my.service");
    return config;
  }

Если я использую SpringBootTest, он запускает веб-сервер, который занимает около 30 секунд, и в идеале я хочу, чтобы все мои тесты завершились менее чем за 5 секунд, иначе разработчики их не запустят.

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class TestNGClass1 extends AbstractTestNGSpringContextTests {

Не думаю, что MockMvc работает с конечными точками Джерси.

1 Ответ

0 голосов
/ 28 августа 2018

Если я использую JerseyTest, мои Spring Beans не загружаются в контекст.

Что вы можете сделать, это установить свойство "contextConfig" в вашем ResourceConfig. Значением будет экземпляр Spring ApplicationContext. Поэтому, если вы используете конфигурацию Java, вы просто используете AnnotationConfigApplicationContext.

@Override
public ResourceConfig configure() {
    return new ResourceConfig()
            .register(TestResource.class)
            .property("contextConfig",
                    new AnnotationConfigApplicationContext(SpringConfig.class));
}

Здесь SpringConfig - произвольный класс Spring @Configuration. Ниже приведен полный пример.

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;

import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.glassfish.jersey.test.inmemory.InMemoryTestContainerFactory;
import org.glassfish.jersey.test.spi.TestContainerFactory;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import static org.assertj.core.api.Assertions.assertThat;


public class SpringTest extends JerseyTest {

    public static class MessageService {
        public String getMessage() {
            return "Hello World";
        }
    }

    @Configuration
    public static class SpringConfig {
        @Bean
        public MessageService service() {
            return new MessageService();
        }
    }

    @Path("test")
    public static class TestResource {
        @Autowired
        private MessageService service;

        @GET
        public String get() {
            return service.getMessage();
        }
    }

    @Override
    public ResourceConfig configure() {
        return new ResourceConfig()
                .register(TestResource.class)
                .property("contextConfig",
                        new AnnotationConfigApplicationContext(SpringConfig.class));
    }

    @Override
    public TestContainerFactory getTestContainerFactory() {
        return new InMemoryTestContainerFactory();
    }

    @Test
    public void testIt() {
        Response res = target("test")
                .request()
                .get();

        String msg = res.readEntity(String.class);
        System.out.println(msg);
        assertThat(msg).isEqualTo("Hello World");
    }
}

Что касается JPA, вам придется настроить его самостоятельно. При использовании Spring Boot все загрузочные JPA-файлы выполняются. Если вы собираетесь использовать Jersey Test Framework, тогда вы игнорируете все настройки Spring Boot.

Это действительно не так сложно настроить JPA самостоятельно. В основном он состоит из настройки DataSource, TransactionManager, JpaVendorAdaptor и LocalContainerEntityManagerFactoryBean. А чтобы включить репозитории Spring Data, вам просто нужно использовать @EnableJpaRepositories.

Посмотрите на этот полный пример конфигурации .

Еще одна вещь, о которой следует опасаться, это то, что когда мы будем использовать Jersey Test Framework, у нас не будет тестовых транзакций (и откатов), которые вы получите при работе с Spring Test. Поэтому, когда вы пишете свои тесты, вы должны принять это во внимание.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...