Как протестировать ehcache с помощью mockito?

Вспомогательный метод Im использует ehcache, чтобы уменьшить количество запросов к Db. Теперь нужно реализовать тест JUnit+Mockito, чтобы убедиться, что ehcache работает правильно. Иметь такой вариант теста:

@Autowired
private DBService service;
@Autowired
private DiscountHelper discountHelper;

@Autowired
private CacheManager cacheManager;

@Before
public void setUp() throws Exception {
    assertNotNull(cacheManager);
}

@Test
public void testGetDiscountWithCache() throws RuntimeException,
        InterruptedException {

    String id1 = "id1";
    String id2 = "id2";
    String id3 = "id3";

    List<String> discountsId = new ArrayList<String>();
    discountsId.add(id1);
    discountsId.add(id2);
    discountsId.add(id3);

    List<Map<String, Object>> attrList = new ArrayList<Map<String, Object>>();
    attrList.add(new Discount().getAttributes());
    attrList.add(new Discount().getAttributes());
    attrList.add(new Discount().getAttributes());

    Cache cache = cacheManager.getCache(DiscountHelper.CACHE_NAME);

    assertNotNull(cache);
    assertEquals(0, cache.getSize());

    // First run with empty cache
    when(service.getAllItems(eq(Discount.TABLE_NAME))).thenReturn(attrList);
    List<Discount> actualResult = discountHelper
            .getAllDiscountsUsingCache();
    assertNotNull(actualResult);
    assertEquals(attrList.size(), actualResult.size());
    verify(service).getAllItems(eq(Discount.TABLE_NAME));

    cache = cacheManager.getCache(DiscountHelper.CACHE_NAME);
    // In cache should be 1 record
    assertNotNull(cache);
    assertEquals(1, cache.getSize());

}

И метод тестирования:

@Cacheable(cacheName = CACHE_NAME, refreshInterval = 1000 * 900, decoratedCacheType = DecoratedCacheType.REFRESHING_SELF_POPULATING_CACHE)
public List<Discount> getAllDiscountsUsingCache() throws RuntimeException,
        InterruptedException {
    List<Map<String, Object>> result = dbService
            .getAllItems(Discount.TABLE_NAME);
    List<Discount> discountList = new ArrayList<Discount>();
    for (Map<String, Object> entry : result) {
        discountList.add(new Discount(entry));
    }
    return discountList;
}

И это прекрасно работает. В тесте я уверен, что после вызова метода я что-то получаю в кеше. Как видите, я также проверяю, был ли вызван метод getAllItems в службе БД. Это хорошо для первого вызова. Затем я добавляю второй вызов DiscountHelper.getAllDiscountsUsingCache() в том же тесте, например:

when(service.getAllItems(eq(Discount.TABLE_NAME))).thenReturn(attrList);
actualResult = discountHelper
            .getAllDiscountsUsingCache();
assertNotNull(actualResult);
assertEquals(attrList.size(), actualResult.size());
verify(service, times(0)).getAllItems(eq(Discount.TABLE_NAME));

Поэтому я просто хочу проверить, что при втором вызове не будет вызовов службы БД через метод getAllItems с помощью этой проверки: verify(service, times(0)).getAllItems(eq(Discount.TABLE_NAME)); и результат будет получен из кеша.

Но это не работает, я все еще получаю вызов метода БД. Я нашел этот учебник http://blog.goyello.com/2010/07/29/quick-start-with-ehcache-annotations-for-spring/ и попробуйте вариант с объектом делегата для тестирования ehcache, но он по-прежнему вызывает методы БД при тестировании. Что не так? Кстати, в продакшене ehcache работает хорошо, как я вижу в логах tomcat, так что это проблема теста. Любые предложения, как это исправить?


person sphinks    schedule 12.04.2013    source источник


Ответы (1)


Во втором вызове вы используете тот же фиктивный объект (сервис), созданный (как я предполагаю из тега вопроса) Springockito во время инициализации контекста Spring. Макет запоминает вызов getAllItems() с первого вызова. Вы можете:

  • сбросить макет перед вторым вызовом, используя reset(service),

or

  • проверьте после второго вызова), есть ли еще один (а не два) вызов getAllItems().
person Marcin Zajączkowski    schedule 13.04.2013