Java 如何使用SpringBoot';JerseyTest测试的上下文

Java 如何使用SpringBoot';JerseyTest测试的上下文,java,rest,testing,spring-boot,jersey,Java,Rest,Testing,Spring Boot,Jersey,我的SpringBoot应用程序中有一些@组件和@资源。 Jersey说,我有正确的JDBC数据源,还有一些REST服务。 我想测试其中一项服务,但它会失败,它说: 自动关联依赖项的注入失败 但它不使用任何组件 这是一个测试db的简单测试,它正在工作: @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = MyApplication.class) public class CommonR

我的SpringBoot应用程序中有一些@组件和@资源。 Jersey说,我有正确的JDBC数据源,还有一些REST服务。 我想测试其中一项服务,但它会失败,它说:

自动关联依赖项的注入失败

但它不使用任何组件

这是一个测试db的简单测试,它正在工作

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MyApplication.class)
public class CommonRepositoryTest {

    @Autowired
    private MyRepository myRepository;

    @Test
    public void testDatabaseChangeLogsSize() {
        int resultSize = myRepository.getTableRowSize(MyTable.TABLE_NAME);
        System.out.println("MyTable result list size: "+resultSize);
        assertTrue("MyTable table should has at least one row!", resultSize>0);
    }

}
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MyApplication.class)
public class SampleResourceTest extends JerseyTest {

    @Override
    protected Application configure() {
        ApplicationContext context = new AnnotationConfigApplicationContext(MyApplication.class);
        return new ResourceConfig(SampleResource.class).property("contextConfig", context);
    }

    @Test
    public void testSampleGet() throws Exception {
        long id = 1;
        String name = "name";
        SampleDomainModel sampleDomainModel = new SampleDomainModel();
        sampleDomainModel.setId(id);
        sampleDomainModel.setName(name);
        Response response = target("/sampleresource/samplepath/" + id).queryParam(name).request().get(Response.class);
        SampleDomainModel responseSampleDomainModel = response.readEntity(SampleDomainModel.class);
        assertEquals(sampleDomainModel.getId(), responseSampleDomainModel.getId());
    }

}
但是此REST测试仪不工作

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MyApplication.class)
public class CommonRepositoryTest {

    @Autowired
    private MyRepository myRepository;

    @Test
    public void testDatabaseChangeLogsSize() {
        int resultSize = myRepository.getTableRowSize(MyTable.TABLE_NAME);
        System.out.println("MyTable result list size: "+resultSize);
        assertTrue("MyTable table should has at least one row!", resultSize>0);
    }

}
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MyApplication.class)
public class SampleResourceTest extends JerseyTest {

    @Override
    protected Application configure() {
        ApplicationContext context = new AnnotationConfigApplicationContext(MyApplication.class);
        return new ResourceConfig(SampleResource.class).property("contextConfig", context);
    }

    @Test
    public void testSampleGet() throws Exception {
        long id = 1;
        String name = "name";
        SampleDomainModel sampleDomainModel = new SampleDomainModel();
        sampleDomainModel.setId(id);
        sampleDomainModel.setName(name);
        Response response = target("/sampleresource/samplepath/" + id).queryParam(name).request().get(Response.class);
        SampleDomainModel responseSampleDomainModel = response.readEntity(SampleDomainModel.class);
        assertEquals(sampleDomainModel.getId(), responseSampleDomainModel.getId());
    }

}
如您所见,它必须覆盖JerseyTest中的configure()方法。 我认为问题在于,注释ConfigApplicationContext无法加载任何内容。 @SpringApplicationConfiguration(classes=MyApplication.class)注释加载上下文,但新注释configApplicationContext(MyApplication.class)代码可能会导致失败,它没有完整的上下文

如果我用mock替换代码,它会工作(但这不是一个好方法):

失败消息是:

2016-05-13 13:25:39.617  WARN 9832 --- [           main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myRepositoryImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.jdbc.core.JdbcTemplate com.repository.impl.myRepositoryImpl.jdbcTemplate; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$JdbcTemplateConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private javax.sql.DataSource org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$JdbcTemplateConfiguration.dataSource; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration$NonEmbeddedConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (no profiles are currently active).
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.422 sec <<< FAILURE! - in com.ws.server.SampleResourceTest
testSampleGetWithCorrectParameters(com.ws.server.SampleResourceTest)  Time elapsed: 0.015 sec  <<< ERROR!
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myRepositoryImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.jdbc.core.JdbcTemplate com.repository.impl.MyRepositoryImpl.jdbcTemplate; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$JdbcTemplateConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private javax.sql.DataSource org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$JdbcTemplateConfiguration.dataSource; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration$NonEmbeddedConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (no profiles are currently active).
    at org.springframework.boot.autoconfigure.jdbc.DataSourceProperties.getDriverClassName(DataSourceProperties.java:180)
    at org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$NonEmbeddedConfiguration.dataSource(DataSourceAutoConfiguration.java:121)
2016-05-13 13:25:39.617 WARN 9832-[main]s.c.a.AnnotationConfigApplicationContext:在上下文初始化过程中遇到异常-取消刷新尝试:org.springframework.beans.factory.BeanCreationException:创建名为“myRepositoryImpl”的bean时出错:自动连线依赖项的注入失败;嵌套异常为org.springframework.beans.factory.BeanCreationException:无法自动关联字段:private org.springframework.jdbc.core.JdbcTemplate com.repository.impl.myRepositoryImpl.JdbcTemplate;嵌套异常为org.springframework.beans.factory.BeanCreationException:创建名为“org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$JdbcTemplateConfiguration”的bean时出错:自动连线依赖项的注入失败;嵌套异常为org.springframework.beans.factory.BeanCreationException:无法自动连接字段:private javax.sql.DataSource org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$JdbcTemplateConfiguration.DataSource;嵌套异常为org.springframework.beans.factory.BeanCreationException:使用类路径资源[org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration$NonEmbeddedConfiguration.class]中定义的名称“dataSource”创建bean时出错:通过工厂方法实例化bean失败;嵌套异常为org.springframework.beans.beanstantiationException:未能实例化[javax.sql.DataSource]:工厂方法“DataSource”引发异常;嵌套异常为org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException:无法确定数据库类型NONE的嵌入式数据库驱动程序类。如果您想要一个嵌入式数据库,请在类路径上放置一个受支持的数据库。如果要从特定配置文件加载数据库设置,则可能需要激活它(当前没有激活的配置文件)。

测试运行:1,失败:0,错误:1,跳过:0,运行时间:0.422秒简单地说,您不能同时使用Spring的TestContext和Jersey测试框架。它们将在两个不同的
ApplicationContext
s上运行。即使尝试将
ApplicationContext
(创建为TestContext)注入测试类并将其传递给
configure
方法中的
ResourceConfig
,也为时已晚,因为注入直到构造之后才发生,但在构造期间调用了`configure方法

忘了
JerseyTest
就用吧。请参阅spring boot项目中的

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(SampleJerseyApplication.class)
@WebIntegrationTest(randomPort = true)
public class SampleJerseyApplicationTests {

    @Value("${local.server.port}")
    private int port;
在Jersey/Boot环境中,Jersey需要在web应用程序环境中运行,
@WebIntegrationTest
就是这样做的

对于客户端,您只需要创建客户端,而不是在
JerseyTest
上调用
target

Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://localhost:" + this.port);

Response response = target.path("/sampleresource/samplepath/" + id).request().get();