2

I'm using scalatest to unit test a class that extends a trait (in the sense that my class is using the trait as a mixin).

The trait contains methods that are helper methods (which ultimately call a few lookups in a database) which I would like to stub out so that I can isolate just the functionality of my class. But I havent been able to find a framework like Mockito or ScalaMock that makes that possible.

Question: Can it be achieved with a mocking framework, and if so how? And if not, I'd be interested to know if there's a reason why.

eg.

trait MyTrait {
  def usefulMethod(i: int) = {...}
}


class MyClass extends MyTrait {
  def numberCruncher = {
     val x = usefulMethod(1) + 1
  }
}

I need to return a different stubbed answer depending on the value of i. Something akin to Mockito's when(myTrait.usefulMethod(1)).thenReturn(10)

I also need to verify that a different method is called in the trait with the correct value.

In essence I am asking this question again but I notice this was asked in 2011, and things may well have moved on. There may be new frameworks and new approaches. This 2001 question also doesnt ask about how to verify methods in the traits.

Question: Do the use of traits-as-a-mixin in this way actually prevent the ability to unit test using a mocking framework to mock/stub methods from the mixin? i.e. Do the mocking and stubbing frameworks depend on the use of dependency injection?

PS. I've been using Mockito until now but I'm not averse to using scalamock or any other framework. I've looked into scalamock because it advertises that it can test traits but from scalamock's own tests it appears that while it can mock traits you can only stub mock the behaviour if that trait is passed as a dependency to a class, rather than a class extending that trait. See here

Community
  • 1
  • 1
moncheery
  • 333
  • 4
  • 17
  • Possible duplicate of [Unit testing helper or non-interface traits in Scala](http://stackoverflow.com/questions/7059859/unit-testing-helper-or-non-interface-traits-in-scala) – Gavin Schulz Nov 14 '15 at 22:07

1 Answers1

2

I generally subclass the class under test to replace methods I want to mock out:

var usefulInput: Option[Int] = Nont
val testInstance = new MyClass {
  override def usefulMethod(i: Int) = {
    usefulInput = Some(i)
    42
  }
}

testInstance.numberCruncher should equal(43)
usefulInput should equal(Some(1))

I find inline overriding generally simpler to implement and read than any mocking framework

Arne Claassen
  • 14,088
  • 5
  • 67
  • 106
  • But do you do that because it's not possible in any other way? that's really what my question is asking. – moncheery Nov 16 '15 at 10:01
  • Hi Arne, i also realised that this method might work to stub out responses, but what if you also needed to verify a method on a trait was called with the correct values? As you would with a mocking framework. – moncheery Nov 16 '15 at 14:33
  • Personally, I've found this form of mocking just easier to comprehend when you come back to it weeks later, since it's so explicit. So I haven't even bothered trying out mocking frameworks with scala. As for verification, you can use a counter, or stuff the args in a list to check. I've done variations of both – Arne Claassen Nov 16 '15 at 16:59
  • Sorry arne - you havent been able to answer my actual question which is whether it's *possible* to do what I'd like to do in an existing framework (in 2015). – moncheery Nov 17 '15 at 11:18