2016-09-13 3 views
1

스프링 응용 프로그램에서 스프링 캐싱 계층을 사용 중이고 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)); 
    } 
} 

예외 :

캐싱 레이어가 작동하지 않아서 호출이 'customer2'mock 객체를 반환 한 리포지토리 개체 (두 번)로 전달 되었기 때문에 "java.lang.AssertionError:"이 표시됩니다. 리포지토리 메서드가 두 번 호출되었습니다. 서비스 계층을 통과하여 동일한 키.

또한 테스트를 위해 "Mockito"프레임 워크를 사용하고 있습니다.

스프링 캐싱에 대한 단위 테스트를 위해 google을 시도했으며 거의 ​​동일한 개념을 사용하는 아래 URL을 참조했지만 위 코드에서는 작동하지 않습니다.

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

당신은 위의 예외를 해결하는 데 도움을 주시겠습니까?

답변

1

스프링 캐쉬 관리자는 애플리케이션 관리 Spring에 의존합니다. 당신은 PowerMockRunner으로 그것을 얻을 수 없다. SpringJUnit4Runner을 사용할 필요가있다. PowerMock 또는 Mockito는 프로그래밍 방식으로 사용할 수 있지만 Runner는 사용할 수 없습니다. 당신의 도움에 대한

@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