2016-09-13 123 views
1

我在我的應用程序中使用了spring緩存層,並且使用Mockito作爲編寫單元測試的一部分來測試彈簧緩存層時出現了問題。Junit for Spring Cache Manager

請參考下面的代碼,我的問題:

服務層:

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」框架。

我曾嘗試谷歌的單元測試在春天緩存和還提到了以下網址,這幾乎是使用相同的概念,但它並不適用於我上面的代碼工作。

How to test Spring's declarative caching support on Spring Data repositories?

能否請您幫助解決上述例外呢?

回答

1

春季緩存管理器依賴於春季管理應用程序。你不能說與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(CustomerService.class); 
     } 
    } 

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

    @Autowired 
    CustomerRepository customerRepository; // this is a mockito mock you can fine-tune 
} 
+0

感謝您的幫助。我正在努力使用Mockito來使它工作。 – developer