-2

I have a Scala class like this:

object MyClient {
  private lazy val theClient: TheClient = new TheClient()
}

class MyClient {
  import MyClient._

  var client = null // this is only for unittest

  def getSomethingFromTheClient() = {
    if (client == null) client = theClient 
    client.getSomething() + " from MyClient" 
  }
}

Some of the code are only there to facilitate unittest, where I can mock TheClient and inject it to MyClient, like this (I am using Mockito):

val mockTheClient = mock[TheClient]
val testMyClient = new MyClient()
testMyClient.client = mockTheClient
testMyClient.getSomethingFromTheClient() shouldBe "blabla"

This works but seems ugly. Ideally if I can inject mockTheClient to the companion object field that would be great. Or am I missing something else?

Mario Galic
  • 47,285
  • 6
  • 56
  • 98
lznt
  • 2,330
  • 2
  • 22
  • 27
  • so I have got four -1s on this question. (and two +1s to be fair.) but none of the -1ers has left any comment. if you think this question is really terrible and should be -1ed, i would really appreciate some idea on why it is so. thanks! – lznt Jun 17 '19 at 19:10

1 Answers1

3

Why don't you just do dependency injection

For example

lazy val client: TheClient = new TheClient()

class MyClient(client: => TheClient) {
  def getSomethingFromTheClient() = {
    client.getSomething() + " from MyClient" 
  }
}

And then in the in the test

val mockTheClient = mock[TheClient]
val testMyClient = new MyClient(mockTheClient)
testMyClient.getSomethingFromTheClient() shouldBe "blabla"
ultrasecr.eth
  • 1,437
  • 10
  • 13
  • Thanks @Bruno! For 1) I want to keep TheClient() lazy. i.e. create MyClient at app start time but only create TheClient when it is actually used. For 2) my code is setter dependency injection, i don't see there is much difference than the constructor dependency injection in your code? – lznt May 21 '19 at 21:31
  • 2
    1) I've modified the answer so the client is lazily created. 2) setter injection requires mutable state, which is something you want to avoid as much as you can (even in Java constructor injection of final fields is considered better than setter injection) – ultrasecr.eth May 22 '19 at 08:21