【问题标题】:How Do I Unit Test A Jersey REST API Without Running A Server?如何在不运行服务器的情况下对 Jersey REST API 进行单元测试?
【发布时间】:2018-08-27 23:58:05
【问题描述】:

我正在使用一个 REST API,它使用带有 Spring Boot 的 Jersey(因此在 XML 或 Java 中没有特定的应用程序上下文)和 Spring Data JPA。

我想在 GET 和 POST 端点上编写单元测试,但是我不想启动 Web 服务器,因为它需要太长时间。

如果我使用 JerseyTest 我的 Spring Bean 不会加载到上下文中。

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 秒的 Web 服务器,理想情况下我希望我的所有测试在 5 秒内完成,否则开发人员将不会运行它们。

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

我认为 MockMvc 不适用于 Jersey 端点。

【问题讨论】:

    标签: spring-boot jersey testng


    【解决方案1】:

    如果我使用 JerseyTest 我的 Spring Bean 不会加载到上下文中。

    您可以在ResourceConfig 中设置属性"contextConfig"。该值将是 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 测试框架,那么您将忽略所有 Spring Boot 配置。

    自己配置 JPA 真的没那么难。它基本上包括配置DataSourceTransactionManagerJpaVendorAdaptorLocalContainerEntityManagerFactoryBean。要启用 Spring Data 存储库,您只需要使用 @EnableJpaRepositories

    看看this complete example configuration

    另一件需要注意的事情是,当我们使用 Jersey 测试框架时,我们不会像使用 Spring Test 那样获得测试范围的事务(和回滚)。因此,当您编写测试时,您需要考虑到这一点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-10-21
      • 1970-01-01
      • 1970-01-01
      • 2016-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多