Spring 缓存管理器的 Junit
Junit for Spring Cache Manager
我在我的应用程序中使用 spring 缓存层,我在编写单元测试以使用 Mockito[=39= 测试 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' 模拟对象,即已通过服务层为同一密钥调用存储库方法两次。
此外,请注意我正在使用 "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
}
我在我的应用程序中使用 spring 缓存层,我在编写单元测试以使用 Mockito[=39= 测试 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' 模拟对象,即已通过服务层为同一密钥调用存储库方法两次。
此外,请注意我正在使用 "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
}