为什么在运行Spring集成测试时没有这种异常

为什么在运行Spring集成测试时没有这种异常,spring,integration-testing,context-configuration,Spring,Integration Testing,Context Configuration,我有一个springboot项目,其中一个开发人员已经针对内存中的DB编写了集成测试。在我提出问题之前,这里有一些背景: 我们有以下Maven模块: 1) web持久性:它存储所有实体、接口和相应的实现。所有这些类都在包com.mycompany.persistence中 2) web服务:存储所有rest控制器和spring安全相关类。这些都在包com.mycompany.services 3) web服务模块对web持久性模块具有maven模块依赖性。 4) 在web服务模块中,我们定义了一

我有一个springboot项目,其中一个开发人员已经针对内存中的DB编写了集成测试。在我提出问题之前,这里有一些背景:
我们有以下Maven模块:
1) web持久性:它存储所有实体、接口和相应的实现。所有这些类都在包
com.mycompany.persistence

2) web服务:存储所有rest控制器和spring安全相关类。这些都在包
com.mycompany.services

3) web服务模块对web持久性模块具有maven模块依赖性。
4) 在web服务模块中,我们定义了一个服务
UserContextServiceImpl
,它是接口
IUserContextService
的实现。该服务基本上封装了Spring的SecurityContextHolder功能,只公开当前用户相关信息中通过其方法所需的部分,这样我们就不必在任何地方使用SecurityContextHolder。实现类用@Service(“userContextService”)注释。
5) 接口
IUserContextService
位于持久性模块中。持久化模块中还有另一个类
AppDependecyHeper
,它实现了
ApplicationContextAware
,并通过调用
appContext.getBean('UserContextService')返回UserContextService的具体实例
其中
appContext
在应用程序初始化时保持
ApplicationContext

6) 现在,我们不想在持久性模块中公开Spring安全类(出于这里上下文之外的原因),也不想通过调用持久性层类
AppDependencyHelper
中applicationContext的
getBean()方法来通过服务获取当前用户信息。然后使用此信息更新由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文件或带注释的类或WebApplicationInitializer(在我的情况下,我们只有一个ApplicationContext),以便从@Configuration类创建
ApplicationContext
。然而,我不能这样做,因为maven开始抱怨循环依赖性,这是正确的,因为我的
@Service
注释类
UserContextServiceImpl
位于web服务模块中,而web服务模块已经依赖于编写测试用例类的web持久性模块。
3) 我能想到的唯一解决方案是将所有集成测试类移动到web服务模块,这样我就可以告诉
@ConfigurationContext
它应该从中创建
应用程序上下文的所有类。我说得对吗

最后一点:当我运行测试时,
ApplicationContext
类的类型是
genericapplicationcontext
。当我运行应用程序时,它显然是
annotateddedwebeapplicationcontext


请告诉我是否有解决此问题的方法?

据我猜测,您试图在集成测试中使用web服务模块中的组件。如果是这样的话,那么您应该将集成测试用例移动到web服务模块中,正如您在问题中所建议的那样

编辑:您应该重新考虑您的设计,因为这里有一个循环依赖性问题:
web服务
模块依赖于
web持久性
,但是
web持久性
中的
IUserContextService
的实现可以在
web服务
中找到


您可能应该将
IUserContextService
(以及所有集成测试)移动到
web服务
包中。

确定。伟大的但是你能告诉我为什么即使我在ComponentScan中添加web服务包,它也不起作用吗?如果我添加更高级别的包(com.mycompany),其中包含其他组件(及其好友)类,那么在测试初始化时会出现不同的错误。但当我添加服务包时,它会初始化,但在运行时会中断。ComponentScan会忽略它吗?而且,即使假设我解决了这个问题,设置SecurityContext的问题仍然存在,我们出现这个问题的原因是我们不想将Spring安全依赖项放在持久化模块中。那么,将其移动到web服务以便在我的集成测试中启用Spring安全性的另一个原因是正确的吗?关于您的第一条评论:当Spring在您的
@组件
类中找不到
@Autowire
d协作者时,您的测试在初始化时失败。当您尝试使用
appContext.getBean('userContextService')
从完全构建的Spring容器中获取Bean时,测试在运行时失败,而这根本不存在,我可以重新启动