Unit testing class that extends a trait - how do I mock and stub methods in the trait?

前提是你 提交于 2019-12-11 10:27:34

问题


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


回答1:


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



来源:https://stackoverflow.com/questions/33711951/unit-testing-class-that-extends-a-trait-how-do-i-mock-and-stub-methods-in-the

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!