Search code examples
javajmockit

Is it possible to use JMockit's Deencapsulation API to exchange method implementation?


So, basically, a there is some poor code that I cannot change that needs to be tested. Traditionally, you inject your mocked dependencies, but with this code, I cannot do so, because there are no setter methods. Worse, the function I need to test calls a bunch of static factory methods-I can't just use the MockUp strategy to swap out the implementation there, because there is no class instance to be injected at all.

In C/++, you can retrieve a pointer to a function and know it's type by it's signature. If you changed the pointer, then you could potentially change how the stack was constructed by the compiler and you could pass function's around and all that Jazz.

Is there a way to use the Deencapsulation API to replace a static method implementation? Using this, I could write my own class, descend from the traditional, but return mocked objects in order that dependency injection still be achieved?

public class TestedClass {
    public static void testedMethod() {
        UnMockableType instanceVariable = 
           UnInjectableFactory.staticFactoryConstructor();
        instanceVariable.preventControlFlowInfluenceThroughMocking();
    }
}

Solution

  • Easy enough:

    @Test
    public void exampleTestUsingAMockUp()
    {
        new MockUp<UnMockableType>() {
            @Mock
            void preventControlFlowInfluenceThroughMocking() {}
        };
    
        TestedClass.testedMethod();
    }
    

    Above, UnInjectableFactory isn't mocked because it doesn't need to be (assuming it simply instantiates/recovers an UnMockableType).

    It could also be done with @Mocked and the Expectations API.