模拟redis模板

问题描述 投票:0回答:8

我在模拟 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"));   
    }    
}
java unit-testing redis mockito spring-data-redis
8个回答
16
投票

你可以像这样模拟 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());
}

3
投票

您正在通过构造函数创建redisTemplate,并且它不是通过DI获取的。尝试使用@Spy注释:

@Spy
private RedisTemplate redisTemplate = new RedisTemplate();

它将允许 DI 注入您的 RedisTemplate 实例。


3
投票

对于那些想要对

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"));
    }

希望对您有帮助;)


2
投票

当我面临类似的任务时,我制作了一个基于 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>

0
投票

我尝试了各种 jedis 模拟库,这是唯一一个使用池资源的库。其他库,服务器甚至没有启动,有些需要本地 redis 启动并运行。这对 junit 来说是最好的

https://github.com/50onRed/mock-jedis


0
投票

即使我也面临着类似的问题。

我修复它的步骤 -

  1. 向我的测试类添加了 @ExtendWith(SpringExtension.class) 注释。
  2. 使用@MockBean注释RedisTemplate
@MockBean
private RedisTemplate<Integer, String> redisTemplate;
  1. 在我的测试方法中,我使用ReflectionTestUtils来设置redisTemplate字段。
ReflectionTestUtils.setField(rm, "redisTemplate", redisTemplate);

0
投票

到达这里有点晚了。下面是我用 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"));
  }
}

0
投票

如果您使用 JUnit-5,这些是您需要注意的事情。

    @BeforeEach
    void setUp() {
        MockitoAnnotations.openMocks(this);
        Mockito.when(redisTemplate.opsForHash()).thenReturn(hashOperations);
        
    }

HashOperations 或 ValueOperations 基于您的要求。

© www.soinside.com 2019 - 2024. All rights reserved.