我的 SpringBoot@Component 和 @Resource em> 申请。 我有正确的 JDBC 数据源,还有一些 REST 服务,由 Jersey 提供。 我想测试其中一项服务,但它会失败,它说:
Injection of autowired dependencies failed
但它不使用任何组件。
这是一个测试数据库的简单测试,它正在运行:
@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);
}
}
但是这个 REST 测试器不工作:
@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() 方法。 我认为问题在于,AnnotationConfigApplicationContext 可能无法加载任何内容(?)。 @SpringApplicationConfiguration(classes = MyApplication.class) 注释加载了上下文,但是 new AnnotationConfigApplicationContext(MyApplication.class) 代码可能会失败,它没有完整的上下文。
如果我用模拟替换代码,它就可以工作(但这不是一个好方法):
@Override
protected Application configure() {
ApplicationContext mockContext = Mockito.mock(ApplicationContext.class);
return new ResourceConfig(SampleResource.class).property("contextConfig", mockContext);
}
失败信息是:
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)
本次 Jersey 测试如何使用SpringBoot上下文?
请您参考如下方法:
简而言之,您不能同时使用 Spring 的 TestContext 和 Jersey 测试框架。它们将在两个不同的 ApplicationContext
上运行。即使您尝试将 ApplicationContext
(创建为 TestContext)注入(inject)测试类并将其传递给 configure
方法中的 ResourceConfig
,为时已晚,因为注入(inject)直到 构造之后才发生,但是 `configure 方法 在 构造期间被调用。
忘记 JerseyTest
并只使用 @WebIntegrationTest
.参见 the sample来自 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();