在将此标记为重复之前,请先阅读问题。我已经阅读了有关此异常的所有内容,但它并没有为我解决问题。我确实得到了一个略有不同的异常,例如Another CacheManager with same name 'myCacheManager' already exists
而不是Another unnamed CacheManager already exists
。
Spring config:
<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)。单独运行此测试类非常合适。
问题是什么?我该如何解决?
答案 0 :(得分:6)
我不知道问题/问题是否仍然相关,但这是一个简单/正确的解决方案(不需要在所有测试中添加@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以添加这两个属性。
不要忘记在每次测试前清除缓存:)
答案 1 :(得分:5)
将@DirtiesContext
注释添加到测试类中:
@ContextConfiguration(...)
@RunWith(...)
@DirtiesContext // <== add e.g. on class level
public class MyTest {
// ...
}
此注释表示与测试关联的应用程序上下文是脏的,应该关闭。随后的测试将提供一个新的背景。适用于类级和方法级。
答案 2 :(得分:3)
即使代码中包含带@Cacheable注释的方法,您也可以运行禁用缓存的测试。
通过使用@DirtiesContext标记所有测试,不必减慢您的测试速度。
将缓存相关的Spring配置放在他们自己的Spring配置文件中,例如。 applicationContext-cache.xml文件。
仅在运行应用程序时包含该applicationContext-cache.xml文件,但不在测试中。
如果您特别想测试缓存,则需要@DirtiesContext注释。
答案 3 :(得分:1)
之所以发生这种情况,是因为在测试期间,同时存在多个Spring应用程序上下文。但是,ehcache是JVM全局的。
通过在类路径上创建spring.properties
文件,您基本上可以禁用Spring上下文缓存:
spring.test.context.cache.maxSize=1
确保在销毁上下文时正确注销了缓存管理器。