Konstantin Bodnia
Konstantin Bodnia

Reputation: 1523

How to mock/stub only one field in a case class

I have seen many articles on how to mock the method in the case class when testing with scalamock.

However, sometimes I need to mock only one field. For example when I'm testing a very narrow workflow.

I thought that stub[Type].copy(f = "1") would do a trick, but it returns only null.

Neither can you mock the field as if it was a method:

val x = mock[Type]
( x.f _ ).when().then("1")

This won't compile as well.

What is the workaround in this situation? What is the best practice in this situation? Should I really define the whole case class fields that I don't need to test?

Upvotes: 2

Views: 1784

Answers (1)

Mario Galic
Mario Galic

Reputation: 48420

ScalaMock does not seem to provide mocking of val fields, which is what case class constructor parameters translate to

Can I mock val / lazy val?

No, the Scala compiler will not allow overriding a val with a def, so with ScalaMock this is not possible.

Other mocking tools might provide it, for example, it works with mockito-scala

class MockitoScalaCaseClassSpec extends AnyFlatSpec with Matchers with IdiomaticMockito with ArgumentMatchersSugar {
  "mockito-scala" should "mock case class fields" in {
    case class User(name: String)
    val userMock = mock[User]
    userMock.name returns "mocked!"
    userMock.name should be("mocked!")
  }
}

It is often argued in favour of not mocking case classes but instead just create an instance. On the other hand, if case class has large number of fields this might become unwieldy: mock case class in scala : Mockito

Upvotes: 5

Related Questions