我有一个CacheService类,它使用scala-redis库的一个实例
class CacheService(redisClient: RedisClient) extend HealthCheck {
private val client = redisClient
override def health: Future[ServiceHealth] = {
client.info
...
}在我的单元测试中,我模拟客户机实例并测试服务
class CacheServiceSpec extends AsyncFlatSpec with AsyncMockFactory {
val clientMock = mock[RedisClient]
val service = new CacheService(clientMock)
"A cache service" must "return a successful future when healthy" in {
(clientMock.info _).expects().returns(Option("blah"))
service.health map {
health => assert(health.status == ServiceStatus.Running)
}
}
}但是我得到了这个编译错误
Error:(10, 24) method pipeline overrides nothing.
Note: the super classes of <$anon: com.redis.RedisClient> contain the following, non final members named pipeline:
def pipeline(f: PipelineClient => Any): Option[List[Any]]
val clientMock = mock[RedisClient]到目前为止,我的研究表明ScalaMock 4不能模拟同伴对象。作者建议用依赖注入重构代码。
如果有进一步的建议,我将不胜感激。我在这里的目标是为我们的外部服务(redis、postgres数据库、电子邮件等)创建一个至少是可测试的健康检查。批评是受欢迎的,因为我对Scala生态系统还不熟悉。
发布于 2020-03-06 08:43:33
我是否正确地做了DI (我选择了构造函数args注入,因为我们的代码库仍然相对较小和简单)?似乎作者建议在客户端实例上放置一个包装器。如果是这样的话,我正在寻找一种惯用的方法。
是的,你是对的,这似乎是一个已知的问题(Link1)。理想情况下,需要对客户端实例进行包装。一种方法可以是创建一个具有方法的特性,比如connect,并将其扩展到RedisCacheDao,并实现connect方法,以便在需要时为您提供客户端实例。然后,您所要做的就是模拟这个连接接口,然后您就可以进行测试了。
另一种方法可以是使用嵌入红进行单元测试--尽管通常是用于集成的-- testing.You可以启动一个简单的redis服务器,在那里通过代码运行测试,并在测试完成后关闭它。
我该去换另一个红宝石图书馆吗?根据redis.io的建议,正在积极维护的库也使用相应的对象。我个人认为这不是这些图书馆的问题。
你当然可以这么做。我更喜欢吉迪斯,因为它很简单,而且它的性能优于scala(同时执行mget)。
如果有帮助请告诉我!!
https://stackoverflow.com/questions/60554307
复制相似问题