【问题标题】:How to use the SpringBoot's context for testing by JerseyTestJerseyTest如何使用SpringBoot的上下文进行测试
【发布时间】:2016-05-13 11:38:07
【问题描述】:

我的 SpringBoot 中有一些 @Component@Resource em> 应用程序。 我有正确的 JDBC 数据源,还有一些 REST 服务,由 Jersey 提供。 我想测试其中一项服务,但它会失败,它说:

自动装配依赖注入失败

但它不使用任何组件。

这是一个测试 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);
    }

}

但是这个 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) strong> 代码可能会失败,它没有完整的上下文。

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

@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)

这个球衣测试如何使用 SpringBoot 上下文?

【问题讨论】:

    标签: java rest testing spring-boot jersey


    【解决方案1】:

    简单地说,你不能同时使用 Spring 的 TestContext 和 Jersey 测试框架。他们将在两个不同的ApplicationContexts 上运行。即使您尝试将ApplicationContext(创建为TestContext)注入测试类并在configure 方法中将其传递给ResourceConfig,也为时已晚,因为直到 构造之后,但`configure 方法被调用 构造中。

    忘记JerseyTest,直接使用@WebIntegrationTest。请参阅 Spring Boot 项目中的 the sample

    @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(); 
    

    【讨论】:

      猜你喜欢
      • 2020-01-17
      • 1970-01-01
      • 2020-09-30
      • 1970-01-01
      • 1970-01-01
      • 2017-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多