我在我的应用程序中使用 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:
”,因为缓存层没有工作并且调用已经传递给存储库对象(两次),它返回了“customer2”模拟对象上面即通过服务层为同一个 key 调用存储库方法两次。
另外,请注意我正在使用“Mockito”框架进行测试。
我曾尝试在 google 上搜索有关 spring 缓存的单元测试,并引用了以下 URL,它几乎使用了相同的概念,但它不适用于我上面的代码。
How to test Spring's declarative caching support on Spring Data repositories?
能否请您帮忙解决上述异常?
最佳答案
Spring 缓存管理器依赖于 Spring 来管理应用程序。您无法通过 PowerMockRunner
获得它,您需要使用 SpringJUnit4Runner
。您仍然可以以编程方式使用 PowerMock 或 Mockito,但不能作为 Runner。
通常,您会将单元测试转换为 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
}
关于java - 用于 Spring 缓存管理器的 Junit,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39475533/