【问题标题】:How to mock a function within Scala object using Mockito?如何使用 Mockito 在 Scala 对象中模拟函数?
【发布时间】:2017-05-30 12:42:15
【问题描述】:

我对 Scala 真的很陌生。我尝试使用 Mockito 模拟一个简单的 Scala 函数,但出现以下错误。我已经检查了互联网,但我无法找出错误。

object TempScalaService {
  def login(userName: String, password: String): Boolean = {
    if (userName.equals("root") && password.equals("admin123")) {
      return true
    }
    else return false
  }
}

我的测试课在下面

class TempScalaServiceTest extends FunSuite with MockitoSugar{

  test ("test login "){
    val service = mock[TempScalaService.type]
    when(service.login("user", "testuser")).thenReturn(true)
    //some implementation
  }
}

但我收到以下错误:

Cannot mock/spy class     com.pearson.tellurium.analytics.aggregation.TempScalaService$
Mockito cannot mock/spy following:
- final classes
- anonymous classes
- primitive types
org.mockito.exceptions.base.MockitoException: 
Cannot mock/spy class    com.pearson.tellurium.analytics.aggregation.TempScalaService$
Mockito cannot mock/spy following:
- final classes
- anonymous classes
- primitive types
   at  org.scalatest.mock.MockitoSugar$class.mock(MockitoSugar.scala:74)
    at    com.pearson.tellurium.analytics.aggregation.TempScalaServiceTest.mock(Temp    ScalaServiceTest.scala:7)
at     com.pearson.tellurium.analytics.aggregation.TempScalaServiceTest$$anonfun$    1.apply$mcV$sp(TempScalaServiceTest.scala:10)
    at    com.pearson.tellurium.analytics.aggregation.TempScalaServiceTest$$anonfun$    1.apply(TempScalaServiceTest.scala:9)
    at     com.pearson.tellurium.analytics.aggregation.TempScalaServiceTest$$anonfun$    1.apply(TempScalaServiceTest.scala:9)
    at    org.scalatest.Transformer$$anonfun$apply$1.apply$mcV$sp(Transformer.scala:    22)
    at org.scalatest.OutcomeOf$class.outcomeOf(OutcomeOf.scala:85)

【问题讨论】:

  • 你不需要在 Scala 中为字符串使用.equals()。试试看:"hi" == new String("hi") 是真的。此外,if (condition) { return true } else return false 可以缩短为 return condition 甚至 condition

标签: scala mockito scalatest


【解决方案1】:

您可以在对象扩展的特征中定义方法。然后简单地模拟特征:

trait Login {
  def login(userName: String, password: String): Boolean
}

object TempScalaService extends Login {
   def login(userName: String, password: String): Boolean = {
     if (userName.equals("root") && password.equals("admin123")) {
   return true
   }
    else return false
  }
}

//in your test
val service = mock[Login]

【讨论】:

  • 此解决方案适用于操作问题,但我注意到在这种方法中它不允许您模拟 login 呼叫。即您不能使用when(mockService.login(any, any)).thenReturn(false),因为当您在模拟服务上调用service.login 时,它仍然在内部调用实际登录。所以你需要提供实际的userNamepassword
【解决方案2】:

你不能模拟对象,试着把你的代码移到一个类中:

class TempScalaService() {
  def login(userName: String, password: String): Boolean = {
    if (userName.equals("root") && password.equals("admin123")) {
      return true
    }
    else return false
  }
}

并创建一个服务:

object TempScalaService {
   private val service = TempScalaService()

   def apply() = service
}

使用依赖注入框架会更好,但它现在可以工作。

现在,为了测试,使用:

val service = mock[TempScalaService]
when(service.login("user", "testuser")).thenReturn(true)

【讨论】:

    【解决方案3】:

    您可以创建一个 Scala 伴侣对象:

    1. 为您的班级编写测试用例。
    2. 让该对象与外部世界交互。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多