2015-11-04 4 views
1

У меня возникли проблемы с получением аннотаций @Cacheable на моих сценариях тестирования JUnit. Похоже, что полностью игнорирует кеширование. Он работает в моем не-тестовом сценарии, но при тестировании нет никаких доказательств того, что он даже касается кеша; нет новых ключей, хэшей, списков, ничего и никаких исключений.@Какетируемый тег, кажется, игнорируется во время тестирования JUnit на Spring

В настоящее время метод, который я пытаюсь тест находится в моей DAO и в основном имитирует медленное соединение (которое не будет медленным, как только кэш вносится в уравнение):

@Component 
public class DAO { 
    @Cacheable(value="slowRetrieval", keyGenerator="simpleKeyGenerator", cacheManager="cacheManager") 
    public boolean slowRetrievalTestIdExists(long testIdValue, long pauseLength) { 
     boolean response = valueExists("id", "test", testIdValue); 

     log.info("Pausing for " + pauseLength + "ms as a part of slow DB transaction simulation"); 
     slowMeDown(pauseLength); 

     return response; 
    } 

    private void slowMeDown(long pause) { 
     try { 
      Thread.sleep(pause); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

Таковы соответствующие биты моего класса тестирования. Они еще не прокомментированы, но TL; DR выполняет метод slowRetrievalTestIdExists несколько раз, а затем повторно запускает его с использованием тех же параметров (поскольку он должен игнорировать тело метода с кешированием). Я уже пытался перенести эти методы в тестовом классе без изменения результатов:

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringApplicationConfiguration(classes={ResultsServiceApplication.class, CacheConfig.class }) 
@DatabaseSetup("TestData.xml") 
@Slf4j 
public class DAOTest { 
    @Autowired 
    private DAO dao; 

    @Test 
    public void cacheTest() { 
     log.info("Testing caching. Deliberately slow database simulations ahead! Be patient please :)"); 
     int maxTests = 5; 
     long pause = 5000l,  //5 seconds 
       estimate, executionTime = 0; 
     List<Map<String, Object>> testIds = getTestData(new String[] {"id"}, "test"); 
     assertNotNull("No test IDs could be retrieved to test caching", testIds); 

     if(testIds.size() < maxTests) maxTests = testIds.size(); 

     estimate = (long)maxTests * pause; 

     log.info("Slow database simulation shouldn't take much more than " + (estimate/1000) + " seconds to complete"); 

     for(int i = 0; i < maxTests; i++) { 
      Long testId = (Long)testIds.get(i).get("id"); 

      log.info("Running simulated slow database transaction " + (i + 1) + " of " + maxTests); 
      boolean result = dao.slowRetrievalTestIdExists(testId, pause); 
     } 

     log.info("Slow database simulations complete (hopefully). Now re-running tests but caching should speed it up"); 

     for(int i = 0; i < maxTests; i++) { 
      Long testId = (Long)testIds.get(i).get("id"); 

      long start = System.currentTimeMillis(); 

      log.info("Re-running simulated slow database transaction " + (i + 1) + " of " + maxTests); 
      boolean result = dao.slowRetrievalTestIdExists(testId, pause); 

      long end = System.currentTimeMillis(); 

      executionTime += (end - start); 
     } 

     executionTime /= (long)maxTests; 

     assertTrue("The second (supposedly cached) run took longer than the initial simulated slow run", 
       Utilities.isGreaterThan(estimate, executionTime)); 
    } 
} 

Вот класс конфигурации кэша (потому что я не был с использованием конфигурации XML на основе):

@Configuration 
@EnableCaching 
public class CacheConfig { 
    @Bean 
    public JedisConnectionFactory redisConnectionFactory() { 
     JedisConnectionFactory redisConnectionFactory = new JedisConnectionFactory(); 

     // Defaults 
     redisConnectionFactory.setHostName("127.0.0.1"); 
     redisConnectionFactory.setPort(6379); 
     return redisConnectionFactory; 
    } 

    @Bean 
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory cf) { 
     RedisTemplate<String, String> redisTemplate = new RedisTemplate<String, String>(); 
     redisTemplate.setConnectionFactory(cf); 

     return redisTemplate; 
    } 

    @Primary 
    @Bean 
    public CacheManager cacheManager(RedisTemplate<String, String> redisTemplate) { 
     RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate); 

     cacheManager.setDefaultExpiration(300l); //300 seconds = 5 minutes 

     return cacheManager; 
    } 

    @Bean(name="cacheManagerLongExpiry") 
    public CacheManager cacheManagerLongExpiry(RedisTemplate<String, String> redisTemplate) { 
     RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate); 

     cacheManager.setDefaultExpiration(604800l); //604,800 seconds = 1 week 

     return cacheManager; 
    } 

    @Bean(name="cacheManagerShortExpiry") 
    public CacheManager cacheManagerShortExpiry(RedisTemplate<String, String> redisTemplate) { 
     RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate); 

     cacheManager.setDefaultExpiration(43200l); //43,200 seconds = 12 hours 

     return cacheManager; 
    } 

    @Bean(name="simpleKeyGenerator") 
     public KeyGenerator keyGenerator() { 
      return new KeyGenerator() { 

       @Override 
       public Object generate(Object o, Method method, Object... objects)      { 
       // This will generate a unique key of the class name, the method name, 
       // and all method parameters appended. 
       StringBuilder sb = new StringBuilder(); 
       sb.append(o.getClass().getName()); 
       sb.append(method.getName()); 

       for (Object obj : objects) { 
        sb.append(obj.toString()); 
       } 

       return sb.toString(); 
      } 
     }; 
    } 
} 

Я был бы очень благодарен за любую помощь в этом, поскольку я был в этом часами, и в Google почти ничего не может быть.

Спасибо! Ed :)

+0

Двойная проверка: 'Utilities.isGreaterThan (оценка, executeTime)' работает так, как вы ожидали. – Ralph

+0

Спасибо, у меня есть, и это определенно работает так, как ожидалось. Однако я не думаю, что это действительно связано с процессом кэширования. Я использую консоль Redis для контроля за производством ключа во время процесса тестирования, и ничто никогда не появляется на протяжении всего процесса – fts9

ответ

0

Итак, я нашел ответ на свой вопрос. Проблема заключалась в том, что я переглядел часть своего кода, что мой метод setUp() переписанный @Autowired DAO. Теперь это было отсортировано, это работает как шарм.

Спасибо всем за помощь! Ed :)

Смежные вопросы