Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking non-public static methods in abstract classes with JMockit?

I have the following class:

public abstract class AbstractParent {
    static String method() {
        return "OriginalOutput";
    }
}

I want to mock this method. I decide to use JMockit. So I create a mock class:

public class MockParent {
    static String method() {
        return "MOCK";
    }
}

And my test code looks like this:

public class RealParentTest {

    @Before
    public void setUp() throws Exception {
        Mockit.redefineMethods( AbstractParent.class, MockParent.class );
    }


    @Test
    public void testMethod() {
        assertEquals(MockParent.method(),AbstractParent.method());
    }

}

Unfortunately this test says that AbstractParent returns "OriginalOutput" instead of "MOCK". Any ideas why? Am I doing something wrong? I've tried declaring my mock class as abstract as well, to no avail.

Edit Note that making the method public causes the test to run without a problem... this is weird because with JMockit you are supposed to be able to mock methods of any scope.

Answer Only the mock method needs to be public, you can leave the original method as is.

like image 821
Epaga Avatar asked Oct 22 '08 07:10

Epaga


People also ask

How can we mock static method of abstract class?

Mocking abstract class using PowerMock mock() is a better approach as it can have control over the private as well as static methods. Step1: Create an abstract class named Abstract_class that contains both abstract and non-abstract methods. Step 2: Create a JUnit test case named AbstractTestClass for testing purposes.

Can abstract class have non static methods?

Abstract classes are similar to interfaces. You cannot instantiate them, and they may contain a mix of methods declared with or without an implementation. However, with abstract classes, you can declare fields that are not static and final, and define public, protected, and private concrete methods.

Can abstract class contains static methods?

Yes, of course you can define the static method in abstract class. you can call that static method by using abstract class,or by using child class who extends the abstract class. Also you can able to call static method through child class instance/object.

Can we override static method in abstract class?

If you declare a method in a class abstract to use it, you must override this method in the subclass. But, overriding is not possible with static methods. Therefore, an abstract method cannot be static.


2 Answers

Found the solution: you simply need to make the mock's method public (the original method can stay in its original visibility).

I don't know why this works while the original way doesn't (someone who does is more than welcome to chime in), but all you need to do is simply change the mock class in the example above to:

public class MockParent {
    public static String method() {
        return "MOCK";
    }
}
like image 92
Epaga Avatar answered Oct 02 '22 14:10

Epaga


Apparently the new way to do this is to use MockUp<T>

new MockUp<AbstractParent>(){
    @Mock String method() {
        return "MOCK";
    }
};

assertEquals("MOCK" AbstractParent.method());

Another alternative is apparently to continue with something like MockParent with a @MockClass annonation. Haven't done this myself as the another inline version does the job.

I've implemented this in an example project on github.

like image 41
Gareth Davis Avatar answered Oct 02 '22 12:10

Gareth Davis