Java 如何使用SpringBoot';JerseyTest测试的上下文
我的SpringBoot应用程序中有一些@组件和@资源。 Jersey说,我有正确的JDBC数据源,还有一些REST服务。 我想测试其中一项服务,但它会失败,它说: 自动关联依赖项的注入失败 但它不使用任何组件 这是一个测试db的简单测试,它正在工作: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
@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();