在使用MRUnit

时间:2016-06-01 12:42:04

标签: mapreduce mocking mockito hadoop2 mrunit

我正在使用mapreduce2创建应用程序并使用MRUnit 1.1.0对其进行测试。在其中一个测试中,我正在检查减速器的输出,该减速器将当前系统时间设置为'在它的输出中。即在reducer执行时,时间戳在context.write()中用于与输出的其余部分一起写入。现在即使我使用相同的方法在测试方法中查找系统时间作为我在reducer中使用的时间,两者中计算的时间通常相隔一秒,如2016-05-31 19:10:022016-05-31 19:10:01。所以两者的输出结果不同,例如:

test_fe01,2016-05-31 19:10:01
test_fe01,2016-05-31 19:10:02

这会导致断言错误。我希望忽略时间戳中的这种差异,因此如果除时间戳之外的其余输出匹配,则测试通过。我正在寻找一种方法来模拟用于返回系统时间的方法,以便返回硬编码值,并且reducer和test都在测试期间使用这个模拟方法。这可能吗?任何帮助将不胜感激。

最好的问候

编辑:我在测试中已经尝试过Mockito的间谍功能:

 MClass mc = Mockito.spy(new MClass());
 Mockito.when(mc.getSysTime()).thenReturn("FakeTimestamp");

但是,这会产生运行时错误:

org.mockito.exceptions.misusing.MissingMethodInvocationException: 
when() requires an argument which has to be 'a method call on a mock'.
For example:
    when(mock.getArticles()).thenReturn(articles);

Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
   Those methods *cannot* be stubbed/verified.
2. inside when() you don't call method on mock but on some other object.
3. the parent of the mocked class is not public.
   It is a limitation of the mock engine.

方法getSysTime()是公开的,静态的,MClass类是公开的,并且没有任何父类。

1 个答案:

答案 0 :(得分:1)

假设我理解了您的问题,您可以使用配置对象将时间传递给Reduce。在您的reduce中,您可以检查是否已设置此配置并使用它,否则您将使用系统时间。

通过这种方式,您可以传入一个已知值进行测试,并断言您可以获得相同的值。