Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Controller Unit Test How do I mock RedisTemplate opsForValue with return type ValueOperations

In my controller I have code like the following. RedisTemplate stringRedisTemplate

def accessRedis()
{
   val = stringRedisTemplate.opsForValue().get('Key')
}

In my controller Test, I intent to inject a mocked RedisTemplate that return a mocked ValueOperations. My code:

def template = mockFor(RedisTemplate)       
def val = mockFor(org.springframework.data.redis.core.ValueOperations)
val.demand.get {p-> println "$p"}
template.demand.opsForValue {
    return val.createMock()
}

controller.stringRedisTemplate = template.createMock()
controller.accessRedis()

However, I got the following error: org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'com.tnd.viewport.ui.AppHawkControllerSpec$_$spock_feature_0_1_closure2@1aa55dd5' with class 'com.tnd.viewport.ui.AppHawkControllerSpec$_$spock_feature_0_1_closure2' to class 'org.springframework.data.redis.core.ValueOperations'

Could you advice a solution for my scenario? Thanks!

like image 843
user3781608 Avatar asked Nov 01 '22 21:11

user3781608


1 Answers

It's simple. Mock them separately.

Eg.

@MockBean
private RedisTemplate<String, String> redisTemplate;
@MockBean
private ValueOperations valueOperations;


@Test
public void testRedisGetKey() {
    // This will make sure the actual method opsForValue is not called and mocked valueOperations is returned
    doReturn(valueOperations).when(redisTemplate).opsForValue();

    // This will make sure the actual method get is not called and mocked value is returned
    doReturn("someRedisValue").when(valueOperations).get(anyString());
}
like image 191
Arjun Nayak Avatar answered Nov 12 '22 10:11

Arjun Nayak