Скаламок не может дифференцировать фьючерсы - PullRequest
0 голосов
/ 01 сентября 2018

У меня есть кусочек скала-кода в классе A.scala Существует класс case Case1, который содержит поле Future для f1, которое относится к типу другого класса case Case2. Case2 включает в себя Seq [String]. Я отправляю объект case2 другому классу B, чей экземпляр - b

case class Case2(list: Seq[String])
case class Case1(f1: Future[Case2])

class A(b: B) {
   def doSomething() {
     val case1 = Case1(Future(Case2(List("Hello")))
     val result = b.doSomethingElse(case1)   // Another future returned
     result
  }
}

class ATest extends .... Some scalatest libraries {
    val bMock = mock[B]
    val a = new A(bMock)
    "A" should {
        "call b" in  {
            val case1 = Case1(Future(Case2(List("Hello")))
            val result = .....Anything....
            (b.doSomethingElse _).expects(case1).returning(Future.successful(result))
             a.doSomething().futureValue shouldBe .....Something
      }
    }
 }

Тест не пройден с сообщением о том, что ложный вызов класса B не совпадает с фактическим. Он печатает ожидаемый и фактический, но они оба выглядят одинаково в журнале.

В идеале тест должен проходить, когда ложный вызов B совпадает с фактическим вызовом B. Но я подозреваю, что это потому, что Case1 заключает в себе Future, который он рассматривает как другой объект. Когда я подставляю подстановочный знак, т.е. (b.doSomethingElse _).expects(*).returning(result).

Есть ли способ пройти этот тест? Я использую scalaMock для насмешливых целей.

1 Ответ

0 голосов
/ 02 сентября 2018

Вы не можете надежно проверить на равенство любую функцию или текущие вычисления, поэтому с:

  • Фьючерсы
  • Задача
  • Бесплатные монады
  • DBIO
  • Типы функций

просто забудьте об использовании на них маршеров (как для утверждений, так и для насмешек).

Для утверждений единственная надежная вещь, которую вы можете сделать, - запустить ее / материализовать результат и отложить утверждение до получения какого-либо фактического значения.

Ваш код не выполняется, потому что в вашем макете вы сравниваете какое-то значение Future (которое, опять же, вы не можете надежно сравнивать с и имитирует внутренне, используя некоторое значение ==, чтобы узнать, наступил ли сейчас момент для возврата имитированного значения).

Поэтому вместо этого попробуйте принять любое значение

(b.doSomethingElse _).expects(*).returning(Future.successful(result))

если в вашем случае это неприемлемо, вы можете заменить expects(*) на что-то вроде expects(where(future => Await.result(future) == something)).

...