首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring测试第二次尝试初始化cache2k,但失败

Spring测试第二次尝试初始化cache2k,但失败
EN

Stack Overflow用户
提问于 2019-07-25 11:38:39
回答 3查看 1.4K关注 0票数 5

在将cache2k添加到我的项目后,一些@SpringBootTest停止了处理错误的操作:

java.lang.IllegalStateException:已创建的缓存:“缓存”

下面我提供了一个复制的最小示例:

转到start.spring.io并使用缓存启动器创建一个最简单的Maven项目,然后添加cache2k依赖项:

代码语言:javascript
复制
<properties>
    <java.version>1.8</java.version>
    <cache2k-version>1.2.2.Final</cache2k-version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.cache2k</groupId>
        <artifactId>cache2k-api</artifactId>
        <version>${cache2k-version}</version>
    </dependency>
    <dependency>
        <groupId>org.cache2k</groupId>
        <artifactId>cache2k-core</artifactId>
        <version>${cache2k-version}</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.cache2k</groupId>
        <artifactId>cache2k-spring</artifactId>
        <version>${cache2k-version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-cache</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

现在配置最简单的缓存:

代码语言:javascript
复制
@SpringBootApplication
@EnableCaching
public class CachingDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(CachingDemoApplication.class, args);
    }

    @Bean
    public CacheManager springCacheManager() {
        SpringCache2kCacheManager cacheManager = new SpringCache2kCacheManager();
        cacheManager.addCaches(b -> b.name("cache"));
        return cacheManager;
    }

}

并添加任何服务(我们将在其中一个测试中进行@MockBean ):

代码语言:javascript
复制
@Service
public class SomeService {
    public String getString() {
        System.out.println("Executing service method");
        return "foo";
    }
}

现在需要两个@SpringBootTest测试来重现这个问题:

代码语言:javascript
复制
@SpringBootTest
@RunWith(SpringRunner.class)
public class SpringBootAppTest {

    @Test
    public void getString() {
        System.out.println("Empty test");
    }
}

@RunWith(SpringRunner.class)
@SpringBootTest
public class WithMockedBeanTest {

    @MockBean
    SomeService service;

    @Test
    public void contextLoads() {
    }
}

注意,第二个测试已经模拟了@MockBean。这会导致错误(下面的堆栈跟踪)。

代码语言:javascript
复制
Caused by: java.lang.IllegalStateException: Cache already created: 'cache'
    at org.cache2k.core.CacheManagerImpl.newCache(CacheManagerImpl.java:174)
    at org.cache2k.core.InternalCache2kBuilder.buildAsIs(InternalCache2kBuilder.java:239)
    at org.cache2k.core.InternalCache2kBuilder.build(InternalCache2kBuilder.java:182)
    at org.cache2k.core.Cache2kCoreProviderImpl.createCache(Cache2kCoreProviderImpl.java:215)
    at org.cache2k.Cache2kBuilder.build(Cache2kBuilder.java:837)
    at org.cache2k.extra.spring.SpringCache2kCacheManager.buildAndWrap(SpringCache2kCacheManager.java:205)
    at org.cache2k.extra.spring.SpringCache2kCacheManager.lambda$addCache$2(SpringCache2kCacheManager.java:143)
    at java.util.concurrent.ConcurrentHashMap.compute(ConcurrentHashMap.java:1853)
    at org.cache2k.extra.spring.SpringCache2kCacheManager.addCache(SpringCache2kCacheManager.java:141)
    at org.cache2k.extra.spring.SpringCache2kCacheManager.addCaches(SpringCache2kCacheManager.java:132)
    at com.example.cachingdemo.CachingDemoApplication.springCacheManager(CachingDemoApplication.java:23)
    at com.example.cachingdemo.CachingDemoApplication$$EnhancerBySpringCGLIB$$2dce99ca.CGLIB$springCacheManager$0(<generated>)
    at com.example.cachingdemo.CachingDemoApplication$$EnhancerBySpringCGLIB$$2dce99ca$$FastClassBySpringCGLIB$$bbd240c0.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:363)
    at com.example.cachingdemo.CachingDemoApplication$$EnhancerBySpringCGLIB$$2dce99ca.springCacheManager(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
    ... 52 more

如果删除@MockBean,则两个测试都将通过。

如何避免测试套件中的错误?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-07-30 18:26:22

由于我不希望测试中存在任何自定义行为,而只是希望消除此错误,因此解决方案是使用以下惟一名称创建CacheManager:

代码语言:javascript
复制
@Bean
public CacheManager springCacheManager() {
    SpringCache2kCacheManager cacheManager = new SpringCache2kCacheManager("spring-" + hashCode());
    cacheManager.addCaches(b -> b.name("cache"));
    return cacheManager;
}
票数 3
EN

Stack Overflow用户

发布于 2019-07-25 11:52:36

第二个测试代表了一个完全不同的ApplicationContext,因此测试框架将为它启动一个专用的测试框架。如果cache2k是有状态的(例如,如果给定的类加载器已经存在,则为它共享CacheManager ),则第二个上下文将尝试在第一个仍然处于活动状态时创建一个新的CacheManager

您需要将其中一个测试标记为脏(请参阅@DirtiesContext),这将关闭上下文并关闭CacheManager,或者可以使用不需要所有这些的选项替换缓存基础结构,请参阅@AutoConfigureCache

如果cache2k的工作方式要求您弄脏上下文,我强烈建议使用后面的选项来交换它。

票数 4
EN

Stack Overflow用户

发布于 2020-06-03 13:33:29

在将cache2k与Spring工具一起使用时,我遇到了同样的错误,最后得到了以下代码作为解决方案:

代码语言:javascript
复制
    @Bean
    public CacheManager cacheManager() {
        SpringCache2kCacheManager cacheManager = new SpringCache2kCacheManager();
        // To avoid the "Caused by: java.lang.IllegalStateException: Cache already created:"
        // error when Spring DevTools is enabled and code reloaded
        if (cacheManager.getCacheNames().stream()
            .filter(name -> name.equals("cache"))
            .count() == 0) {
            cacheManager.addCaches(
                b -> b.name("cache")
            );
        }
        return cacheManager;
    }
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57201103

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档