jmockit / jmockit1

Advanced Java library for integration testing, mocking, faking, and code coverage
Other
465 stars 240 forks source link

$advice does not work with interfaces #653

Closed Horcrux7 closed 4 years ago

Horcrux7 commented 4 years ago

I run the follow test program:

package x;

import mockit.Invocation;
import mockit.Mock;
import mockit.MockUp;

public class ATest {

    public static void main( String[] args ) {
        new MockInterface();
        TestInterface.staticCall();
        TestClass instance = new TestClass();
        instance.interfaceCall();

        new MockClass();
        TestInterface.staticCall();
        instance.interfaceCall();
    }

    static class MockInterface extends MockUp<TestInterface> {
        @Mock
        Object $advice( Invocation invocation ) {
            System.out.println( "MockInterface advice called, on " + invocation.getInvokedMember().getName() );
            return null;
        }
    }

    static class MockClass extends MockUp<TestClass> {
        @Mock
        Object $advice( Invocation invocation ) {
            System.out.println( "MockClass advice called, on " + invocation.getInvokedMember().getName() );
            return null;
        }
    }

    interface TestInterface {
        static void staticCall() {
            System.out.println( "staticCall() directly" );
        }

        void interfaceCall();
    }

    static class TestClass implements TestInterface {
        @Override
        public void interfaceCall() {
            System.out.println( "interfaceCall() directly" );
        }
    }
}

It produce the follow output:

staticCall() directly
interfaceCall() directly
staticCall() directly
MockClass advice called, on interfaceCall

It look like that the static method can't mock with $advice and interface methods also not. In the documentation I can't find any related. Is this a limit of JMockit or a bug?

Horcrux7 commented 4 years ago

Ok, for interfaces I need a anonymous Mockup class. This is tricky. Then it work.

    public static <T extends TestInterface> void main( String[] args ) {
        new MockUp<T>() {
            @Mock
            Object $advice( Invocation invocation ) {
                System.out.println( "MockInterface advice called, on " + invocation.getInvokedMember().getName() );
                return null;
            }
        };