tim tim
tim tim

Reputation: 13

scala - unit test - How to mock a class method inside a class

I have a class in Scala that looks like this:

class A {
  private val b = new B()

  def doSomething() {
    b.someMethod();
  }
}

How can I unit test doSomething()? How can I mock b here?

I tried something like this:

val b = mock[B]
when(b.someMethod()).thenReturn(xx)
val class_to_test = new A()
class_to_test.doSomething()

I am using Mockito and MockitoSugar.

Upvotes: 1

Views: 4573

Answers (1)

Brian McCutchon
Brian McCutchon

Reputation: 8594

The problem with your last code snippet is that val b = mock[B] is a different variable from the b field of your class. You can fix this by modifying the class to take b as an optional argument:

class A(b: B = new B) {
  def doSomething(): Unit = {
    b.someMethod()
  }
}

Now your test becomes:

val b = mock[B]
when(b.someMethod()).thenReturn(xx)
val classToTest = new A(b)
classToTest.doSomething()

This technique is called Dependency Injection. You can read more about it here: What is dependency injection?


If you don't want to expose b as a public constructor parameter, you can use a package-private constructor coupled with a public constructor or factory method that provides the default value of b:

class A private[myPackage](b: B) {
  def this() = this(new B)  // The public constructor doesn't expose b.

  def doSomething(): Unit = {
    b.someMethod()
  }
}

Then just make sure your tests are in the same package so they can still call the constructor that takes b.

Upvotes: 3

Related Questions