8

在将其标记为重复之前,请先阅读问题。我已经阅读了有关此异常的所有内容,但它并没有为我解决问题。而且我确实得到了一个稍微不同的异常,例如Another CacheManager with same name 'myCacheManager' already exists而不是Another unnamed CacheManager already exists.

弹簧配置:

<cache:annotation-driven cache-manager="cacheManager"/>

<bean id="cacheManager"
      class="org.springframework.cache.ehcache.EhCacheCacheManager"
      p:cacheManager-ref="ehcache"/>
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
      p:configLocation="ehcache.xml"
      p:cacheManagerName="myCacheManager"
      p:shared="true"/>

ehcache

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
        updateCheck="false" name="myCacheManager">

</ehcache>

问题是我有 1 个(将来会更多)测试安全性的测试类。这些类还加载一个 SecurityContext.xml

所以大多数测试类都有这个注释:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:ApplicationContext.xml")

但是导致问题的类:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
    "classpath:ApplicationContext.xml",
    "classpath:SecurityContext.xml"
})

似乎由于位置不同,因此再次加载了上下文,但 ehcacheManager 在之前的测试中仍然处于活动状态。

注意:这仅在运行多个测试时发生(例如,像 clean + build)。单独运行这个测试类可以很好地工作。

什么问题?我该如何解决?

4

4 回答 4

8

向您的测试类添加@DirtiesContext注释:

@ContextConfiguration(...)
@RunWith(...)
@DirtiesContext // <== add e.g. on class level
public class MyTest {
    // ...
}

此注释指示与测试关联的应用程序上下文是脏的,应该关闭。随后的测试将提供一个新的上下文。适用于类级别和方法级别。

于 2013-02-23T12:14:31.347 回答
7

我不知道问题/问题是否仍然相关,但这是一个简单/正确的解决方案(不需要在所有测试中添加 @DirtiesContext )。避免 @DirtiesContext 允许您为所有集成测试只有一个共享上下文(例如,通过 maven 运行,或在 IDE 中运行所有测试)。这避免了由同时启动的多个上下文引起的多个问题。

<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
  p:configLocation="ehcache.xml"
  p:cacheManagerName="myCacheManager"
  p:shared="${ehcacheManager.shared:true}"
  p:acceptExisting:"${ehcacheManager.acceptExisting:false}"/>

在您的测试(集成测试)中,设置这些属性

ehcacheManager.acceptExisting=true
ehcacheManager.shared=false

它允许 Spring 为每个测试创建一个 EhcacheManager (ehcache),但如果存在同名的 EhcacheManager,Spring 只会重用它。并且 Spring 也不会在使用 @DirtiesContext 注释的上下文中销毁/关闭它。

这个想法很简单,你可以在使用@DirtiesContext 时防止 EhcacheManager 的破坏。

如果您使用 Spring 4 和 EhCache:2.5+,则适用。在 Spring 3 中,您必须扩展 EhCacheManagerFactoryBean 才能添加这两个属性。

不要忘记在每次测试之前清除缓存:)

于 2015-11-30T12:23:28.933 回答
4

即使您的代码具有带有 @Cacheable 注释的方法,您也可以在禁用缓存的情况下运行测试。

这样,您不必通过使用@DirtiesContext 标记所有测试来减慢测试运行速度。

缓存相关的 Spring 配置放在他们自己的 Spring 配置文件中,例如。applicationContext-cache.xml 文件。

仅在实时运行应用程序时包含该 applicationContext-cache.xml 文件,而不是在您的测试中。

如果你特别想测试缓存,那么你需要 @DirtiesContext 注释。

于 2014-06-25T06:02:03.483 回答
1

发生这种情况是因为在测试期间,同时存在多个 Spring 应用程序上下文。但是,ehcache 是 JVM 全局的。

您基本上可以通过spring.properties在类路径上创建文件来禁用 Spring 上下文缓存:

spring.test.context.cache.maxSize=1

确保在销毁上下文时正确取消注册缓存管理器。

于 2019-08-12T09:19:53.467 回答