debasishg / scala-redis

A scala library for connecting to a redis server, or a cluster of redis nodes using consistent hashing on the client side.
1.02k stars 219 forks source link

RedisClient.pipeline not possible to mock for testing #217

Open chris-zen opened 6 years ago

chris-zen commented 6 years ago

I have a function like:

def write(redisClient: RedisClient) = {
  redisClient.pipeline { pipe =>
    pipe.set("k1", "v1")
    pipe.set("k2", "v2")
  }
}

Given that the type of pipe is RedisClient.this.PipelineClient and PipelineClient is an Inner Class, it is not possible to write something like this in a test (the code doesn't compile because it is not possible to import PipelineClient):

val redisClient: RedisClient = mock[RedisClient]
val pipelineClient: PipelineClient = mock[PipelineClient]
when(redisClient.pipeline(any())).thenAnswer((invocation: InvocationOnMock) => {
  invocation.getArgument[PipelineClient => Any](0).apply(pipelineClient)
})

I see that PipelineClient is implemented as an Inner Class, but used as an Static Class, as it receives a reference to its parent, and all the accesses to it are done through the reference.

I am wondering if it could be possible to make PipelineClient an static class so pipelining can be easily mocked. I could prepare the PR if you wish.

mjuanes commented 4 years ago

Same issue here, I think I'll choose another library.

solyd commented 4 years ago

this works for me (am able to refer to PipelineClient as a type):

  val tmp = mock[RedisClient]
  def pipeline(f: tmp.PipelineClient => Any): Option[List[Any]] = {
    // ...
  }
noahlz commented 2 years ago

I also encountered this... PipelineClient is documented but not accessible. Not sure I understand the why you wouldn't at least expose this as a trait? Unless we should just be using RedisCommand?

https://www.javadoc.io/doc/net.debasishg/redisclient_2.12/3.20/com/redis/RedisClient.html#PipelineClientextendsRedisCommandwithPubOperations