使用Mockito

时间:2019-01-28 11:18:50

标签: scala mockito

我有一个与链接类似的问题:How to mock a function within Scala object using Mockito?

我有一个对象FooInner,其方法为stringData,该方法需要int并给出字符串输出

object FooInner {
  def stringData(data: Int): String = {
    data match {
      case 1 => "one"
      case _ => "else"
    }
  }
}

另一个对象FooOuter调用FooInner来获取字符串数据并对其执行一些操作。

object FooOuter {
  def dummyCall(data: Int): String = {
    FooInner.stringData(data) + "some operation"
  }
}

我的目标是测试方法FooOuter.dummyCall的字符串数据,而不是FooInner.stringData返回的数据

同样,我按照上述文章并创建了特征

trait TFooInner {
  def stringData(data: Int): String
}

将FooInner的签名更改为

object FooInner extends TFooInner {..}

并创建了测试类FooTests

class FooTests extends FlatSpec with Matchers with MockitoSugar{
  "dummyCall" should "mocked data" in {
    val service = mock[TFooInner]
    when(service.stringData(1)).thenReturn("1")    // mocked service data -> 1
    assert(FooOuter.dummyCall(1) === "1-some operation")   // TestFailedException:  "[one]-some operation" did not equal "[1]-some operation"
  }
}

,但是我仍然无法获得模拟的服务数据“ 1”。 我有以下问题:

  • 如何使FooOuter可以通过FooInner未返回的数据进行测试
  • 在Scala中编码是否正确的功能样式?我的感觉是FooOuter现在紧密耦合/依赖于FooInner

斯卡拉:2.11
Mockito:1.9.5

1 个答案:

答案 0 :(得分:6)

您必须同时改变InnerOuter对象,使它们可测试的。

通常,如果您想存根它们进行测试,则永远不要直接调用object方法。此类方法应通过实例调用来实现和访问:

  class FooInner {
     def stringData(data: Int): String = { ... }
  }

  object FooInner extends FooInner

   class FooOuter(inner: FooInner) {
     def dummyCall(data: Int): String = inner.stringData(data) + "bar"
   }

   object FooOuter extends FooOuter(FooInner)

现在,在测试中,您可以

   val inner = mock[FooInner]
   val testMe = new FooOuter(inner)
   when(inner.stringData(any)).thenReturn("foo")
   testMe.dummyCall(1) shouldBe "foobar"
   verify(inner).stringData(1)