你如何在Mockito中模拟scala的呼叫名称

时间:2015-11-02 21:44:09

标签: scala unit-testing mockito scala-java-interop

我试图在mockito中模拟scala call-by name方法。但遇到这个错误。

  

如果匹配器与原始值组合,则可能会发生此异常:       //不正确:       someMethod(anyObject(),“raw String”);使用匹配器时,所有参数都必须由匹配器提供。例如:       //正确:       someMethod(anyObject(),eq(“by matcher”));

任何建议都将不胜感激。谢谢!

以下是示例代码和测试文件:这里我试图模拟 createCommand 功能。并给出一个模拟,以便我可以验证是否调用 执行

  package com.example

  class Command(key: String, func: => Long) {
    def execute(): Long = {
      println("Command.execute")
      println("key = " + key)
      println("func = " + func)
      func
    }

  }

  class CacheHelper {


    def createCommand(cacheKey: String, func: => Long): Command = {
      println("cacheKey = " + cacheKey)
      println("func = " + func)
      new Command(cacheKey, func)
      //    Mock this method
    }

    def getOrElse(cacheKey: String)(func: => Long): Long = {

      println("circuitBreakerEnabled = " + isCircuitBreakerEnabled)
      if (isCircuitBreakerEnabled) {
        val createCommand1: Command = createCommand(cacheKey, func)
        println("createCommand1 = " + createCommand1)
        createCommand1.execute()
      }
      else {
        util.Random.nextInt()
      }
    }

    def isCircuitBreakerEnabled: Boolean = {
      println("CacheHelper.isCircuitBreakerEnabled")
      false
    }
  }

  import com.example.{CacheHelper, Command}
  import org.mockito.Matchers._
  import org.mockito.Mockito._
  import org.scalatest.{Matchers, _}
  import org.scalatest.mock.MockitoSugar

  class ExampleSpec extends FlatSpec with Matchers with BeforeAndAfter with MockitoSugar {

    "it" should "call commands execute" in {
      val cacheHelper: CacheHelper = new CacheHelper
      val commandMock: Command = mock[Command]
      val spyCacheHelper = spy(cacheHelper)

      when(spyCacheHelper.isCircuitBreakerEnabled).thenReturn(true)
      when(spyCacheHelper.createCommand(any(), anyLong())).thenReturn(commandMock)

      val result: Long = spyCacheHelper.getOrElse("key")(1L)
      println("result = " + result)
      verify(commandMock).execute()

    }

  }

2 个答案:

答案 0 :(得分:2)

无法与Mockito合作:Verifying by-name parameters in Mockito

应该可以用scalamock来做到这一点: How to mock a call-by-name argument (like getOrElse) using ScalaMock?

答案 1 :(得分:1)

您可以使用https://github.com/mockito/mockito-scala

import com.example.{CacheHelper, Command}
import org.mockito.ArgumentMatchersSugar._
import org.mockito.IdiomaticMockito
import org.scalatest.{Matchers, _}

  class ExampleSpec extends FlatSpec with Matchers with BeforeAndAfter with IdiomaticMockito {

    "it" should "call commands execute" in {
      val cacheHelper: CacheHelper = new CacheHelper
      val commandMock: Command = mock[Command]
      val spyCacheHelper = spy(cacheHelper)

      spyCacheHelper.isCircuitBreakerEnabled shouldReturn true
      spyCacheHelper.createCommand(any[String], any[Long]) shouldReturn commandMock 

      val result: Long = spyCacheHelper.getOrElse("key")(1L)
      println("result = " + result)
      verify(commandMock).execute()

    }

  }