Как пройти класс scala в макете

У меня есть класс Scala A и в нем есть метод doSomething.

Есть еще класс B

  class B(name: String)

есть еще один класс C

class C {
 def doSomethingElse(b: B): String { 
 /// some logic 

 ////

 }
} 


 class A(c: C) {
  def doSomething(uuid: UUID): String {
   val b = new B("hello)
   c.doSomethingElse(b)
   // some logic

 }

}

Теперь я хочу протестировать метод doSomething класса A с использованием scalatest и scalamock.

и я пытался издеваться над звонком doSomethingElse

val mockC = mock[C] 
val b = new B("hello")
(mockC.doSomethingElse _).expects(b).returning("A");

но когда происходит фактический вызов, макет не удовлетворяется, потому что объект B другой. Есть ли способ выразить это издевательство, чтобы оно удовлетворилось?


person user9920500    schedule 28.09.2019    source источник
comment
Если вы хотите, чтобы new B("hello") рассматривался как равный другому new B("hello"), вы должны реализовать .equals соответственно. По умолчанию используется идентификатор экземпляра Java (равен только один и тот же экземпляр). Если B может быть кейс-классом, вы получите это бесплатно.   -  person Thilo    schedule 28.09.2019


Ответы (2)


Комментарий Тило правильный - ваши два B будут сравниваться как ссылки выше, и, поскольку они не являются одним и тем же объектом, они не равны. Для равенства содержимого вам нужна соответствующая equals реализация. Вы получите это бесплатно в Scala, если сделаете B case class. Если вы не можете изменить класс B, то использование матрицы предикатов в ScalaMock может помочь вам сравнить два экземпляра во время теста. Прочтите об этом здесь: https://scalamock.org/user-guide/matching/

person Philipp    schedule 28.09.2019
comment
но мой класс не case, и он не должен быть только для того, чтобы пройти тесты. Есть ли другой трюк, который можно использовать только для тестов? - person user9920500; 28.09.2019
comment
Вы уже читали и пробовали сопоставление предикатов, как я советовал выше? Если это не сработает для вас, значит, по сути, нет никакого способа, а просто так работает JVM. - person Philipp; 28.09.2019

Вот примеры, предложенные @Thilo и @PhilippM:

Переопределение такого метода equals

class B(val name: String) {
  override def equals(obj: Any): Boolean = obj match {
    case b: B => b.name == this.name
    case _ => false
  }
}

мы можем использовать обычные

(mockC.doSomethingElse _) expects(new B("hello")) returning("A")

или если мы не можем изменить B, попробуйте сопоставление предикатов вот так

mockC.doSomethingElse _ expects where { (b: B) => b.name == new B("hello").name } returning "A"
person Mario Galic    schedule 28.09.2019