Mockito无法模拟Hadoop Mapper上下文

时间:2019-02-26 17:22:47

标签: java scala hadoop mapreduce mockito

因此,我尝试使用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)

1 个答案:

答案 0 :(得分:1)

考虑到您正在使用Scala,您似乎正在使用旧版本的Mockito-core,强烈建议您改用最新版本的mockito-scala

此外,只要有可能,作为一种好的实践,您应该避免嘲笑您不拥有的类。 更好的方法是将与第三方的交互包装在一个类(或一组类)中,并进行集成测试以证明它们按预期工作。

在系统的其余部分上,您注入了这些类,因此,为了进行测试,您对上述类进行了模拟,这使您可以控制(并简化)公开的接口,并在第三版的未来版本中最大程度地减少中断方lib更改其API。

有关更多详细信息,请在Mockito博客上查看此StackOverflow answer和此post