Tweaking an output before testing using MRUnit

43 Views Asked by At

I am using creating an application using mapreduce2 and testing the same using MRUnit 1.1.0. In one of the tests, I am checking the output of a reducer which puts the 'current system time' in it's output. I.e. at the time the reducer executes, the timestamp is used in context.write() to be written along with the rest of the output. Now even though I use the same method to find the system time in the test method as the one I use in the reducer, the times calculated in both are generally a second apart, like 2016-05-31 19:10:02 and 2016-05-31 19:10:01. So the output in the two turns out to be different, example:

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

This causes an assertion error. I wish to ignore this difference in timestamps, so the tests pass if the rest of the output apart from the timestamp is matched. I am looking for a way to mock the method used for returning the system time, so that a hardcoded value is returned, and the reducer and the test both use this mocked method during the test. Is this possible to do? Any help will be appreciated.

Best Regards

EDIT: I have already tried Mockito's spy functionality in the my test:

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

However, this gives a runtime error:

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.

The method getSysTime() is public and static and class MClass is public and doesn't have any parent classes.

1

There are 1 best solutions below

3
Binary Nerd On

Assuming i understand your question, you could pass a time into the Reduce using the configuration object. In your reduce you could check if this configuration is set and use it, otherwise you use the system time.

This way you can pass in a known value for testing and assert you get that same value back.