user9920500
user9920500

Reputation: 695

How to pass a scala class in a mock

I have a scala class A and there is a method doSomething in it.

There is another class B

  class B(name: String)

there is another class 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

 }

}

Now I want to test the method doSomething of class A using scalatest and scalamock

and I tried to mock the call doSomethingElse

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

but when the actual call happens , the mock does not get satisfied because the object of B is different. Is there a way to express this mock so that it gets satisfied ?

Upvotes: 0

Views: 260

Answers (2)

Mario Galic
Mario Galic

Reputation: 48410

Here are examples suggested by @Thilo and @PhilippM:

Overriding equals method like so

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

we can use regular

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

or if we cannot modify B then try predicate matching like so

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

Upvotes: 0

Philipp
Philipp

Reputation: 967

Thilo's comment is right - your two Bs would be compared as references above, and as they are not the same object, they are not equal. For content equality, you need an appropriate equals implementation. You get that for free in Scala if you make B a case class. If you can't change class B though, then using a predicate mather in ScalaMock might help you to compare the two instances during the test. Read up on it here: https://scalamock.org/user-guide/matching/

Upvotes: 1

Related Questions