'Mock redis template

I am facing a issue in mock redis template. Can any one help me to write unit test for below class.

@Repository
public class CasheRepo {

    @Autowired
    private RedisTemplate<String, Object> template;

    public Object getObject(final String key) {
    return template.opsForValue().get(key);
    }
}

And below is unit test class. But it is not working. It shows null point exceptions

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


Solution 1:[1]

you can mock redisTemplate like this:

@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());
}

Solution 2:[2]

You are creating redisTemplate via constructor, and it was not got by DI. Try to use @Spy annotation:

@Spy
private RedisTemplate redisTemplate = new RedisTemplate();

It will allow DI to inject your instance of RedisTemplate.

Solution 3:[3]

While I faced with a similar task, I've made a tool(annotation) based on mock-jedis to solve it in easy way. You could read about it here: https://github.com/incu6us/redis-mock-template or just add a dependency to your project:

<dependency>
  <groupId>com.github.incu6us.redis</groupId>
  <artifactId>redis-mock-template</artifactId>
  <version>0.0.1</version>
</dependency>

Solution 4:[4]

For those who want to do the same with HashOperations get() and 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"));
    }

Hope it helps you ;)

Solution 5:[5]

I tried various jedis mock libraries, this is the only one worked with pooled resource. Other libraries, the server did not even start and some required local redis to be up and running. this is the best for junit

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

Solution 6:[6]

Even I was facing a similar issue.

Steps to the way I fixed it -

  1. Added @ExtendWith(SpringExtension.class) annotation to my test class.
  2. Anotated the RedisTemplate with @MockBean
@MockBean
private RedisTemplate<Integer, String> redisTemplate;
  1. In my test method, I used ReflectionTestUtils to set the redisTemplate field.
ReflectionTestUtils.setField(rm, "redisTemplate", redisTemplate);

Solution 7:[7]

Arriving bit late here . My answer below with 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"));
  }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Jean-Philippe Briend
Solution 2 MaximSadym
Solution 3 Viacheslav Pryimak
Solution 4 Adarsh D
Solution 5 webjockey
Solution 6 Mitali Bhokare
Solution 7 Nikhil Rao