【问题标题】:Tweaking an output before testing using MRUnit在使用 MRUnit 测试之前调整输出
【发布时间】:2016-06-01 12:42:04
【问题描述】:

我正在使用 mapreduce2 创建一个应用程序并使用 MRUnit 1.1.0 对其进行测试。在其中一项测试中,我正在检查减速器的输出,该减速器将“当前系统时间”放入其输出中。 IE。在 reducer 执行时,context.write() 中使用时间戳与输出的其余部分一起写入。现在,即使我在测试方法中使用与在减速器中使用的方法相同的方法来查找系统时间,但两者计算的时间通常相隔一秒,如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 和测试在测试期间都使用这个模拟的方法。这可能吗?任何帮助将不胜感激。

最好的问候

编辑:我已经在我的测试中尝试了 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 是公共的并且没有任何父类。

【问题讨论】:

    标签: mapreduce mocking mockito hadoop2 mrunit


    【解决方案1】:

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

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

    【讨论】:

    • 听起来像是一个解决方案,但是如果不向reducer添加任何代码就不能这样做吗?我想在我的测试中模拟在我的应用程序中实现的String getSysTime() 方法(并返回当前系统时间),以便该方法返回一个硬编码的时间戳。
    • 您可以扩展您的 reducer 并覆盖该方法,或者使用 Mockito 之类的东西来模拟该特定方法:stackoverflow.com/questions/14970516/…
    • 该方法不在我的减速器类中,并且有一个很长的调用链,通过它返回时间戳。我发布的问题有很多抽象和简化。配置解决方案还需要我将配置对象添加到链中涉及的所有方法的参数列表中。该解决方案可能会奏效,但会导致许多不必要的复杂性和回归。在我的情况下,一个理想的解决方案是在我的测试中模拟一个特定类的一个特定方法,但我不确定如何实现。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-05
    • 2017-03-29
    • 2023-03-30
    • 1970-01-01
    相关资源
    最近更新 更多