如何等待Redis缓存缓存信息
How to wait for Redis cache to cache the information
我正在使用 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());
}
在分布式系统中等待很短的时间时会出现运行时问题。为了弥补测试断言等待时间过长的需要,有一个名为 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 触发一些第一个请求。
实际问题不在于线程等待时间。要使 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());
}
我正在使用 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());
}
在分布式系统中等待很短的时间时会出现运行时问题。为了弥补测试断言等待时间过长的需要,有一个名为 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 触发一些第一个请求。
实际问题不在于线程等待时间。要使 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());
}