当前位置: 首页 > 知识库问答 >
问题:

用于Spring缓存管理器的Junit

贾飞鸿
2023-03-14

我在我的应用程序中使用了spring缓存层,我在编写使用Mockito测试spring缓存层的单元测试时遇到了一个问题。

    public CustomerServiceImpl implements CustomerService {
    @Autowired
    private CacheManager cacheManager;

    @Autowired
    private CustomerRepository customerRepository;//Repository is simple JPA repository interface which contains findByCustomerName()

    @Override
    @CachePut(value = "#customer", key = "#customer.customerName")
    public Customer insertOrUpdate(Customer customer) {
        return customerRepository.save(customer);
    }

    @Cacheable(value="customersCache", key = "#customerName")
    public Customer findByCustomerName(String customerName) {
        Customer customer = customerRepository.findByCustomerName(customerName);
        return customer;
    }
}

服务层的JUnit测试代码

@RunWith(PowerMockRunner.class)
@PrepareForTest(CustomerServiceImplTest.class)
public class CustomerServiceImplTest {

    @Spy
    CacheManager cacheManager = new ConcurrentMapCacheManager("customersCache");

    @Mock
    CustomerRepository CustomerRepository;

    @InjectMocks
    CustomerServiceImpl customerServiceImpl = new CustomerServiceImpl();

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testCacheForFindByCustomerName() {
        Customer customer1 = new Customer();
        customer1.setId("1");
        customer1.setName("John");
        Customer customer2 = new Customer();
        customer2.setId("2");
        customer2.setName("Sara");

        //this should save to cache   
        Mockito.when(CustomerRepository.save(customer1))
        .thenReturn(customer1);
        customerServiceImpl.insertOrUpdate(customer1);

        //Now it should retreive from cache, but not able to
      Mockito.when(CustomerRepository.findByCustomerName(Mockito.any(String.class)))
                .thenReturn(customer1, customer2);

        Customer result = customerServiceImpl.findByCustomerName("John");
        assertThat(result, is(customer1));

        result = customerServiceImpl.findByCustomerName("John");
        assertThat(result, is(customer1));
    }
}

例外情况:

我得到了一个“java.lang.AssertionError:”,因为缓存层没有工作,并且调用被传递到repository对象(两次),该对象返回了上面的'Customer2'模拟对象,即通过传递服务层,对同一个键调用了两次repository方法。

共有1个答案

麻和雅
2023-03-14

Spring缓存管理器依赖于Spring管理应用程序。您无法用PowerMockRunner实现这一点,您需要使用SpringJunit4Runner。您仍然可以以编程方式使用PowerMock或Mockito,但不能作为运行器使用。

通常,您将把单元测试转换为Spring样式的集成测试,如下所示:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class SpringTest {

    @Configuration
    @EnableCaching
    static class SpringConfig{
        @Bean
        public CustomerService customerService(){
            return new CustomerServiceImpl(customerRepository());
        }
        @Bean
        public CustomerRepository customerRepository(){
            return Mockito.mock(CustomerRepository.class);
        }
    }

    @Autowired
    CustomerService customerService; // this will contain a proper managed cache

    @Autowired
    CustomerRepository customerRepository; // this is a mockito mock you can fine-tune
}
 类似资料:
  • 我试图使用Spring Boot与咖啡因和一些注释函数。在我们的测试中,对控制器endpoint的异步调用出现了一些问题,这些问题似乎与我们使用非异步缓存的事实有关。 在做一些研究时,我看到了很多使用Caffeine手动使用的例子,但是在和Spring Boot和注释中找不到任何东西。看起来和具有非常不同的API。是否可以异步使用默认的Spring Boot? 谢谢

  • 目前,我正在使用带有Ehcache的@缓存来使用Spring cache。我将使用Spring Data Redis 2.0.3用Redis替换Ehcache。我在网上看到的所有示例都是基于旧版本的,但是新版本有不同格式的构造函数。 这是我当前的cacheManager配置: 基于旧版本使用Redis的示例如下: 新版本中的构造函数与旧版本完全不同,新版本的所有示例都像这样手动将所有内容放入缓存:

  • 为spring boot应用程序集成EhCache3缓存提供程序。我需要决定使用哪个缓存管理器。理想情况下,我希望在我的缓存方法上使用Springs缓存注释,例如@Cacheable,而不是jsr(@CacheResult),但对于cachemanager/cache库,我无法决定以下内容 我决定使用ehcache3提供程序进行缓存库注释: 对哪种实施方式有何建议?也许我不清楚上面的实现有什么不同

  • 我在SpringBootApplication中实现了缓存,如下所示 那么,如果我们不定义CacheManager将使用什么呢?

  • 我有一个Spring启动项目,它作为一个库(打包的jar文件)到其他一些项目。我试图哟配置咖啡因缓存,将异步刷新请求后,向服务。 pom.xml(包括): 我的配置类: DAO层(此处需要缓存): DAO层(这里也需要缓存): 运行此安装程序时,我遇到以下错误堆栈: 不确定设置中缺少什么?

  • 我正在探索Ignite事务性缓存。我已经有了一段代码,它对JDBC使用Spring事务管理。我想使用Spring缓存抽象在代码中集成ignite事务性缓存。 我遇到了SpringTransactionManager(由Ignite提供),但我无法找到正确的使用方法。本质上,我想做一些类似的事情: 当事务提交时,数据库和缓存应该一起提交。为此,Ignite文档提到了使用SpringTransacti