来自Scala的模拟Java静态类

pau*_*aul 7 java scala mockito scalatest java-8

知道如何从 ScalaTest 模拟静态 Java 类吗?

我有这个代码

  val mockMapperComponent: IMapperComponent = mock[IMapperComponent]
  val applicationContext: ApplicationContext = mock[ApplicationContext]

  val appContextUtil: AppContextUtil = mock[AppContextUtil]


  override def beforeAll(): Unit = {
    mockStatic(classOf[AppContextUtil])
    when(AppContextUtil.getApplicationContext).thenReturn(applicationContext)
    when(applicationContext.getBean(classOf[IMapperComponent])).thenReturn(mockMapperComponent)

  }
Run Code Online (Sandbox Code Playgroud)

在 Java 中mockStatic使用类中的注释@PrepareForTest({AppContextUtil.class})可以解决问题,但从 Scala 中我只能在 scalaTest 文档中找到如何模拟正常访问,而不是静态访问。

问候。

Vad*_*kan 3

Scala 中的 Mocking Java 静态方法比 Java 中涉及更多,因为 Mockito API 使用 Java 的能力将单函数接口隐式转换为函数指针,例如: httpClientStaticMock.when(HttpClientBuilder::build).thenReturn(httpClientBuilder);通知函数指针用法: HttpClientBuilder::build

由于 scala 编译器没有相同的隐式转换规则,我们必须显式地对该调用进行脱糖:

val httpClientStaticMock = mockStatic(classOf[org.apache.http.impl.client.HttpClientBuilder])
try {
  httpClientStaticMock.when(new org.mockito.MockedStatic.Verification {
    override def apply(): Unit = org.apache.http.impl.client.HttpClientBuilder.create()
  }).thenReturn(httpClientBuilder)

} finally {
  httpClientStaticMock.close()
}

Run Code Online (Sandbox Code Playgroud)

注意匿名对象使用来实现Verification接口:new org.mockito.MockedStatic.Verification

另外,请注意并且不要忘记子句close中的静态模拟finally,否则将很难排除错误。