konquestor
konquestor

Reputation: 1308

mock case class in scala : Mockito

In my play application i intend to mock a case class. I am able to do so but it creates an object with all member variables null. Is there a way to create mock objects of a case classes such that the object can have some members initialized?

case class User(name: String, address: String)    
val mockUser = mock[User]
user.name // null
user.address //null

how do i create a mockUser such that i can assign some values to name and address?

Edit:

I need the ability to mock the object because i want to have predefined behavior of one of the member method. (This member method calls an external service and i dont want the external service call while doing a unit test.) The member method is called inside another member method, which i want to test.

Upvotes: 4

Views: 8675

Answers (3)

Jeremy Townson
Jeremy Townson

Reputation: 113

I would move your external service call out of the case class, into a service class and then mock this service class.

Usually, case classes represent data. It leads to neater code if data and the functions which use that data (e.g. your external call) are separate.

I would write code like

case class User(name: String, address: String)

class UserService {
  def callExternalService(user: User): Result = ???
}

val testUser = User("somebody", "somewhere")
val mockService = mock[UserService]
when(mockService.callExternalService(testUser)).thenReturn(...)

Upvotes: 0

Nick
Nick

Reputation: 8317

It should be as simple as this:

when(mockUser.name).thenReturn("Bob")

As far as:

You should never need to mock case classes. It's like "mocking an integer".

False. (IMHO)

What's wrong with val mockUser = User("mockName", "mockAddress")?

Nothing if you dont think there's anything wrong with

val mockFoo = FooWith20Properties("1", "2", "3",..."20")

Your tests will work but you've missed the point of using a mocking framework to reduce your test boilerplate.

Having said that there does seem to be a divide between those that think case classes should be final and those that dont. If you mark yours final then mocking wont work without resorting to something equally controversial such as Powermock.

Upvotes: 22

Dima
Dima

Reputation: 40510

You should never need to mock case classes. It's like "mocking an integer".

What's wrong with val mockUser = User("mockName", "mockAddress")?

Upvotes: 7

Related Questions