【发布时间】:2016-03-26 21:52:42
【问题描述】:
我有一个 Spring Boot 项目,其中一位开发人员针对内存数据库编写了集成测试。在我提出问题之前,这里有一些背景:
我们有以下 Maven 模块:
1) web-persistence :存储所有实体和接口以及相应的实现。所有这些类都在包com.mycompany.persistence中。
2) web-services :它存储了我们所有的 rest 控制器和 spring 安全相关的类。这些都在包com.mycompany.services
3) web-services 模块对 web-persistence 模块有 maven 模块依赖。
4) 在 web-services 模块中,我们定义了一个服务UserContextServiceImpl,它是接口IUserContextService的实现。该服务基本上封装了 Spring 的 SecurityContextHolder 功能,只公开其方法所需的当前用户相关信息的那些部分,这样我们就不必在任何地方使用 SecurityContextHolder。实现类用@Service("userContextService")注解。
5) 接口IUserContextService 在持久化模块中。在持久化模块中还有另一个类AppDependecyHeper,它实现了ApplicationContextAware,并通过调用appContext.getBean('userContextService')返回UserContextService的具体实例,其中appContext在应用程序初始化时持有ApplicationContext。
6) 现在我们不想在持久性模块中公开 Spring Security 类(因为这里没有上下文的原因),因此通过在持久层类 AppDependencyHelper 中调用 getBean() method of applicationContext 通过服务获取当前用户信息的上述安排.然后使用此信息更新审计字段 createdBy 和 modifiedBy 使用 EntityListener.
7) 实际应用程序仅使用单个 ApplicationContext,其中持久层类和 Web 控制器都加载在一个 Spring 上下文中。
8) 应用程序运行时一切正常。然而,当我们的集成测试运行调用 appContext.getBean('userContextService') 失败并抛出 NosuchBeanDefinitionException 因为它无法找到名为“userContextService”的 bean
9) 现在是位于com.mycompany.persistence.embeddeddb 包中的集成测试代码(仅给出相关细节):
@Runwith(SpringJUnit4ClassRunner.class)
@ConfigurationContext
class MyEntityTest{
@Configuration
@ComponentScan("com.mycompany.persistence")
public static class Config{
.....
}
.....//code which eventually gives call to
AppDependencyHelper's method which in turn tries to retrieve userContextService Bean.
}
现在的问题:
1) 为什么它无法检索 bean?我试过像下面这样添加com.mycompany.services
@ComponentScan({"com.mycompany.persistence","com.mycompany.services"})
但无济于事。
2)通过阅读我得到的任何内容,我能够理解的是,@ContextConfiguration 需要提供 XML 文件或带注释的类或 WebApplicationInitializers(在我的情况下,因为我们只有一个 ApplicationContext)才能从@配置类。但是我不能这样做,因为 maven 开始抱怨循环依赖,这是正确的,因为我的 @Service 带注释的类 UserContextServiceImpl 在 web-services 模块中,该模块依赖于 web-persistence 模块已经编写了测试用例类。
3) 我能想到的唯一解决方案是将所有集成测试类移动到 Web 服务模块,这样我就可以告诉 @ConfigurationContext 它应该从中创建 ApplicationContext 的所有类。对吗?
最后一点:当我运行测试时,ApplicationContext 类的类型是 GenericApplciationContext。当我运行应用程序时,它显然是AnnotatedEmbeddedWebApplicationContext
如果有解决这个问题的办法,请告诉我?
【问题讨论】:
-
只是为了确定:你的类是如何调用的,它实现了
IUserContextService?你是坚持使用默认的 bean 命名约定还是使用@Component(value = "userContextService")给它一个替代的 bean 名称? -
我觉得我们忽略了参考 Spring 手册的正确部分来帮助您解决问题....同样,这个问题非常大
标签: spring integration-testing context-configuration