【问题标题】:Mockito cannot mock Hadoop Mapper ContextMockito 无法模拟 Hadoop 映射器上下文
【发布时间】:2019-07-20 07:37:18
【问题描述】:

所以我正在尝试使用 Mockito 为我的 Hadoop 映射函数创建一个单元测试。我已经正确创建了 Mapper 类:

class XmlMapper extends Mapper[LongWritable, Text, Text, LongWritable] {

    override def map(key: LongWritable, value: Text, context: Mapper[LongWritable, Text, Text, LongWritable]#Context): Unit = {
        //does stuff
    }
}

然后我有以下测试:

import org.apache.hadoop.io.{LongWritable, Text}
import org.scalatest.FlatSpec
import org.scalatest.mockito.MockitoSugar
import org.mockito.Mockito.verify
import org.mockito.Mockito.times

class XmlMapperTest extends FlatSpec with MockitoSugar {

    "XmlMapper" should "output" in {
        val mapper = new XmlMapper
        val context = mock[mapper.Context]
        //so far does nothing yet
    }
}

但我收到以下错误:

- should output *** FAILED ***
[info]   org.mockito.exceptions.base.MockitoException: Mockito cannot mock this class: class org.apache.hadoop.mapreduce.Mapper$Context.
[info]
[info] Mockito can only mock non-private & non-final classes.
[info] If you're not sure why you're getting this error, please report to the mailing list.

这没有意义,因为 Mapper.Context 是一个公共抽象类。

这是总堆栈跟踪:

[info] Underlying exception : java.lang.UnsupportedOperationException: Cannot define class using reflection
[info]   at org.scalatest.mockito.MockitoSugar.mock(MockitoSugar.scala:73)
[info]   at org.scalatest.mockito.MockitoSugar.mock$(MockitoSugar.scala:72)
[info]   at XmlMapperTest.mock(XmlMapperTest.scala:7)
[info]   at XmlMapperTest.$anonfun$new$1(XmlMapperTest.scala:11)
[info]   at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
[info]   at org.scalatest.OutcomeOf.outcomeOf(OutcomeOf.scala:85)
[info]   at org.scalatest.OutcomeOf.outcomeOf$(OutcomeOf.scala:83)
[info]   at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104)
[info]   at org.scalatest.Transformer.apply(Transformer.scala:22)
[info]   at org.scalatest.Transformer.apply(Transformer.scala:20)

【问题讨论】:

  • 您使用的是哪个版本的 Mockito 和 Hadoop?我刚试过你的代码,它可以工作......
  • 我正在使用 hadoop-mapreduce-client-core 2.8.1 和 mockito-core 2.8.47。使用 Java 版本 10、Java HotSpot(TM) 64 位服务器 VM 版本 10,全部在 Windows 10 上。
  • 嗯,那个版本的 mockito-core 似乎很旧,无论如何,如果你使用的是 scala,你可能想转移到 mockito-scala,我尝试了 v1.1.5,它适用于你的 hadoop 依赖项...也就是说,我必须指出,理想情况下,您希望避免模拟您不拥有的类作为一种良好做法
  • 谢谢!迁移到 mockito-scala 是有效的。
  • 如果模拟类不理想,您对 Hadoop 的单元测试有何建议?

标签: java scala hadoop mapreduce mockito


【解决方案1】:

您似乎使用的是旧版本的 mockito-core,鉴于您使用的是 Scala,我强烈建议您使用最新版本的 mockito-scala

此外,作为一种良好做法,您应该尽可能避免模拟您不拥有的类。 更好的方法是将与第 3 方的交互封装在一个类(或一组类)中,并进行集成测试以证明它们按预期工作。

在系统的其余部分,您注入这些类,因此,为了测试,您模拟了这些类,这允许您控制(和简化)公开的接口,并且还可以最大限度地减少中断,以防万一第三个版本的未来版本派对库更改其 API。

有关更多详细信息,请查看 Mockito 博客上的 StackOverflow answerpost

【讨论】:

  • 谢谢!更新 mockito-core 或将其换成 mockito-scala 帮助我解决了在为旧项目运行测试时遇到的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-10
  • 1970-01-01
  • 1970-01-01
  • 2015-12-28
  • 2016-03-07
相关资源
最近更新 更多