代码之家  ›  专栏  ›  技术社区  ›  opticyclic

如何在不运行服务器的情况下对Jersey REST API进行单元测试?

  •  1
  • opticyclic  · 技术社区  · 8 年前

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

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

    如果我使用 JerseyTest 我的春豆并没有被加载到上下文中。

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

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

    我不认为 MockMvc 使用Jersey端点。

    1 回复  |  直到 8 年前
        1
  •  0
  •   Paul Samsotha    8 年前

    如果我使用 JerseyTest 我的春豆并没有被加载到上下文中。

    你能做的就是设置属性 "contextConfig" 在你的 ResourceConfig . 值将是弹簧 ApplicationContext 实例。因此,如果使用Java配置,您将只使用 AnnotationConfigApplicationContext .

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

    在这里, SpringConfig 是任意的弹簧 @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引导时,所有的JPA引导都会得到处理。如果要使用Jersey测试框架,那么将忽略所有Spring引导配置。

    自己配置JPA其实并不难。它基本上包括配置 DataSource A TransactionManager A JpaVendorAdaptor ,和 LocalContainerEntityManagerFactoryBean . 为了启用Spring数据存储库,您只需要使用 @EnableJpaRepositories .

    看看 this complete example configuration 。

    另一件需要注意的事情是,当我们使用Jersey测试框架时,我们将没有您在使用Spring测试时将得到的测试范围的事务(和回滚)。所以在编写测试时,需要考虑到这一点。

    推荐文章