Search code examples
javajunitlog4jjmockit

How to remove jMockit Fake/MockUp for abstract method?


Because I can't fake an abstract class directly and I know the implementing class, I added the fake to the implementing class.

@BeforeClass
public static void fakeCurrentYear() {
    // Mocking the abstract 'Calender' does not work, see: https://github.com/jmockit/jmockit1/issues/71
    // So we use the implementing class 'GregorianCalendar'.
    new MockUp<GregorianCalendar>() {

        @Mock public int get(Invocation invocation, int field) {
            return 2016;
        }
    };
}

I'm using jMockit v 1.31 with JUnit 4.12 and Maven 3.x.

When I execute tests individually, everything is fine.

But when I execute all tests together, another test fails because the log4jlogger in the implementing class obviously uses the fake-implementation.

I think this is because previously GregorianCalendar did not overwrite that method. However, I thought the fake is automatically removed after the testclass! Is this a bug?

Can I remove it manually? I've tried stepping back to JMockit v1.25, created a static variable yearMock = new MockUp<GregorianCalendar>() ... and calling yearMock.tearDown() in a @AfterClass method, but it didn't change anything.


Solution

  • I've used a workaround, where I created a method in the class under test with just a single line of code

    private int currentYear4digits() {
        return Calendar.getInstance().get(Calendar.YEAR);
    }
    

    In my test I then mocked this method.

    @BeforeClass
    public static void fakeCurrentYear() {
        new MockUp<MyClass>() {
    
            @Mock 
            public int currentYear4digits() {
                return 2016;
            }
        };
    }
    

    However, this is just a workaround. It would be cumbersome if the calls to Calendar where made from several classes.