Не удается смоделировать класс RedisClient - конвейер метода ничего не переопределяет - PullRequest
0 голосов
/ 06 марта 2020

У меня есть класс 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 НЕ способен насмехаться над сопутствующими объектами. Автор предлагает рефакторинг кода с помощью Dependency Injection.

  • Правильно ли я делаю DI (я выбрал инжекцию аргументов конструктора, поскольку наша кодовая база все еще относительно мала и проста)? Похоже, автор предлагает поместить оболочку на экземпляр клиента. Если так, я ищу идиоматический подход c.
  • Должен ли я заморачиваться с заменой другой библиотеки redis? Библиотеки, которые активно поддерживаются, по предложению redis.io, также используют сопутствующие объекты. Я лично думаю, что это не проблема этих библиотек.

Буду признателен за любые дальнейшие рекомендации. Моя цель здесь - создать проверку работоспособности для наших внешних сервисов (redis, postgres база данных, электронная почта и т. Д.), По крайней мере, для тестирования. Критика приветствуется, так как я все еще плохо знаком с экосистемой Scala.

1 Ответ

0 голосов
/ 06 марта 2020

Правильно ли я делаю DI (я выбрал инжекцию аргументов конструктора, поскольку наша кодовая база все еще относительно мала и проста)? Похоже, автор предлагает поместить оболочку на экземпляр клиента. Если так, я ищу идиоматический подход c.

Да, вы правы, и это, кажется, известная проблема (ссылка 1). В идеале, необходимо обернуть вокруг экземпляра клиента. Один из подходов может состоять в том, чтобы создать признак с методом, скажем connect, расширить его до RedisCacheDao и реализовать метод connect, чтобы предоставить вам экземпляр клиента, когда вам потребуется. Затем все, что вам нужно сделать, это смоделировать этот интерфейс подключения, и вы сможете провести тестирование.

Другой подход может заключаться в использовании встроенного redis для модульного тестирования. хотя обычно он используется для интеграционного тестирования. Вы можете запустить простой сервер Redis, на котором тесты выполняются с помощью кода, и закрыть его, как только тестирование будет завершено.

Стоит ли мне поменяться местами с другим Redis библиотека? Библиотеки, которые активно поддерживаются, по предложению redis.io, также используют сопутствующие объекты. Я лично думаю, что это не проблема этих библиотек.

Вы, конечно, можете это сделать. Я бы предпочел Jedis , поскольку это просто, и его производительность лучше, чем scala -redis (при выполнении mget).

Дайте мне знать, если это поможет! !

...