我在模拟 Redis 模板中遇到问题。 任何人都可以帮我为下面的课程编写单元测试吗?
@Repository
public class CasheRepo {
@Autowired
private RedisTemplate<String, Object> template;
public Object getObject(final String key) {
return template.opsForValue().get(key);
}
}
下面是单元测试类。但它不起作用。它显示空点异常
@RunWith(MockitoJUnitRunner.class)
public class CashRepoTest {
@InjectMocks
private CasheRepo casheRepo = new CasheRepo();
private @Mock RedisConnection redisConnectionMock;
private @Mock RedisConnectionFactory redisConnectionFactoryMock;
private RedisTemplate redisTemplate;
@Before
public void setUp() { Mockito.when(redisConnectionFactoryMock.getConnection()).thenReturn(redisConnectionMock);
redisTemplate = new RedisTemplate();
redisTemplate.setConnectionFactory(redisConnectionFactoryMock);
redisTemplate.afterPropertiesSet();
}
@Test
public void getObjectTest() {
Mockito.doNothing().when(redisTemplate).opsForValue().set("spring", "data");
redisTemplate.afterPropertiesSet();
System.out.println(redisTemplate.opsForValue().get("spring"));
}
}
你可以像这样模拟 redisTemplate :
@Mock
RedisTemplate<String, String> redisTemplate;
@Mock
private ValueOperations valueOperations;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
Mockito.when(redisTemplate.opsForValue()).thenReturn(valueOperations);
Mockito.doNothing().when(valueOperations).set(anyString(), anyString());
}
您正在通过构造函数创建redisTemplate,并且它不是通过DI获取的。尝试使用@Spy注释:
@Spy
private RedisTemplate redisTemplate = new RedisTemplate();
它将允许 DI 注入您的 RedisTemplate 实例。
对于那些想要对
HashOperations
get()
和 put()
做同样事情的人
@Mock
RedisTemplate<String, String> redisTemplate;
@Mock
private HashOperations hashOperations;
@Test
void getFromCache() {
Mockito.when(redisTemplate.opsForHash()).thenReturn(hashOperations);
when(hashOperations.get("test-key", "test-hash-key")).thenReturn("value123");
RedisCacheServiceImpl cacheService = new RedisCacheServiceImpl(redisTemplate);
assertEquals("value123", cacheService.getFromCache("test-key", "test-hash-key"));
}
希望对您有帮助;)
当我面临类似的任务时,我制作了一个基于 mock-jedis 的工具(注释)来以简单的方式解决它。您可以在这里阅读:https://github.com/incu6us/redis-mock-template 或者只是向您的项目添加依赖项:
<dependency>
<groupId>com.github.incu6us.redis</groupId>
<artifactId>redis-mock-template</artifactId>
<version>0.0.1</version>
</dependency>
我尝试了各种 jedis 模拟库,这是唯一一个使用池资源的库。其他库,服务器甚至没有启动,有些需要本地 redis 启动并运行。这对 junit 来说是最好的
即使我也面临着类似的问题。
我修复它的步骤 -
@MockBean
private RedisTemplate<Integer, String> redisTemplate;
ReflectionTestUtils.setField(rm, "redisTemplate", redisTemplate);
到达这里有点晚了。下面是我用 Junit5 的回答
@ExtendWith(MockitoExtension.class)
class CashRepoTest {
@InjectMocks
CashRepo cashRepo;
@Mock
RedisTemplate<String, Object> template;
@Mock
ValueOperations<String, Object> valueOperations;
@Test
void getTest() {
Mockito.when(template.opsForValue())
.thenReturn(valueOperations);
String expectedValue = "ev";
when(valueOperations.get("test")).thenReturn(expectedValue);
assertEquals(expectedValue, cashRepo.getObject("test"));
}
}
如果您使用 JUnit-5,这些是您需要注意的事情。
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
Mockito.when(redisTemplate.opsForHash()).thenReturn(hashOperations);
}
HashOperations 或 ValueOperations 基于您的要求。