Mapreduce 在使用MRUnit进行测试之前调整输出

Mapreduce 在使用MRUnit进行测试之前调整输出,mapreduce,mocking,mockito,hadoop2,mrunit,Mapreduce,Mocking,Mockito,Hadoop2,Mrunit,我正在使用mapreduce2创建一个应用程序,并使用MRUnit1.1.0对其进行测试。在其中一个测试中,我正在检查减速机的输出,该减速机将“当前系统时间”放入其输出中。也就是说,在执行reducer时,时间戳将用于context.write()中,与其他输出一起写入。现在,尽管我在测试方法中使用了与我在减速器中使用的方法相同的方法来查找系统时间,但在这两种方法中计算的时间通常相差一秒,如2016-05-31 19:10:02和2016-05-31 19:10:01。因此,这两种方法的输出结果

我正在使用mapreduce2创建一个应用程序,并使用MRUnit1.1.0对其进行测试。在其中一个测试中,我正在检查减速机的输出,该减速机将“当前系统时间”放入其输出中。也就是说,在执行reducer时,时间戳将用于
context.write()
中,与其他输出一起写入。现在,尽管我在测试方法中使用了与我在减速器中使用的方法相同的方法来查找系统时间,但在这两种方法中计算的时间通常相差一秒,如
2016-05-31 19:10:02
2016-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
是公共的,没有任何父类。

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


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

听起来像是一种解决方案,但如果不向减速机添加任何代码,就不可能这样做吗?我想模拟应用程序中实现的
字符串getSysTime()
方法(返回当前系统时间),在我的测试中,这个方法返回一个硬编码的时间戳。你可以扩展你的reducer并重写这个方法,或者使用类似Mockito的东西来模拟这个特定的方法:这个方法不在我的reducer类中,并且有一个很长的调用链,通过它返回时间戳。我发布的问题有很多抽象和简化。配置解决方案还需要我将配置对象添加到链中涉及的所有方法的参数列表中。解决方案可能会奏效,但会导致许多不必要的复杂性和回归。在我的例子中,一个理想的解决方案是在我的测试中模拟某个类的某个特定方法,但我不确定如何实现它。