如何等待Redis缓存来缓存信息

时间:2019-03-25 18:12:19

标签: java spring redis spring-data spring-cache

我正在使用spring-data-redis并尝试使用一个junit,可以测试我的缓存逻辑。测试用例偶尔起作用。我猜想如果缓存逻辑在调用第二个方法调用之前完成,那么它将起作用,否则它将失败。如果有些人遇到了类似的问题,我想了解他们是如何使其工作的。到目前为止,我正在使用thread.sleep(),但正在寻找替代方法。

  @Test
  public void getUserById() {
  User user = new User("name", "1234");
when(userRepository.findbyId("1234")).thenReturn(Optional.ofNullable(user));
  // first method call
  User user1 = userService.findbyId("1234");

  assertThat(user.getName()).isEqualTo(user1.getName());
  assertThat(user.getId).isEqualTo(user1.getId());

  // sleeping the thread so to provide caching aspect sufficient time 
  // to cache the information
  try {
    Thread.sleep(1000);
  } catch (InterruptedException e) {
    e.printStackTrace();
  }
  // second method call, expecting cache to work.
  userCache = userService.findbyId("1234");
  verify(userRepository, never()).findbyId("1234");
  assertThat(user.getName()).isEqualTo(userCache.getName());
  assertThat(user.getId).isEqualTo(userCache.getId());
}

2 个答案:

答案 0 :(得分:0)

在短时间内等待时会出现运行时问题,这在分布式系统中确实很常见。为了弥补等待时间太长的测试断言的需要,有一个名为Awaitility的小工具。

基本上,您可以通过多次查询一个断言来进行更聪明的等待,在一定的时间间隔内,直到达到给定的超时时间为止(……甚至更多)。

关于您的示例,请尝试以下操作:

        Awaitility.await()
                .pollInterval(new Duration(1, TimeUnit.SECONDS))
                .atMost(new Duration(10, TimeUnit.SECONDS))
                .untilAsserted(() -> 
                    User user1 = userService.findbyId("1234");
                    assertThat(user1.getName()).isEqualTo(user.getName());

关于问题的另一部分,在集成测试中,您实际上可以对您的Redis实例执行某种预热,或者如果您有容器化的集成测试(例如Docker),则可以在它或wait for a certain condition,然后再开始测试。

答案 1 :(得分:0)

实际问题与线程等待时间无关。为了使Redis缓存正常工作,需要跨越一个单独的线程。对于我的服务测试,我通过一个单独的测试用例对其进行了测试。

 @Test
 public void getUserById() {
   User user = new User("name", "1234");
   when(userRepository.findbyId("1234")).thenReturn(Optional.ofNullable(user));
    // first method call
   User user1 = userService.findbyId("1234");
   assertThat(user.getName()).isEqualTo(user1.getName());
   assertThat(user.getId).isEqualTo(user1.getId());
 }
 //ensure this test case is executed after getUserById. I used 
 //@FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Test
 public void getUserById_cache() {
   User user1 = userService.findbyId("1234");
   Mockito.verify(userRepository, never()).findbyId("1234")
   assertThat(user.getName()).isEqualTo(user1.getName());
   assertThat(user.getId).isEqualTo(user1.getId());
 }