简体   繁体   中英

java - reflection: How to Override private static abstract inner class method?

I have the following class:

class MyClass{

    private static final int VERSION_VALUE = 8;

    private static final String VERSION_KEY = "versionName";

    public boolean myPublicMethod(String str) {
        try { 
            return myPrivateMethod(str, VERSION_KEY, VERSION_VALUE,
                    new MyInnerClass() {

                    @Override
            public InputStream loadResource(String name) {
                            //do something important
                        }
                    });
        }
        catch (Exception e) {           
        }
        return false;
    }


private boolean myPrivateMethod(String str, String key, int version,
            ResourceLoader resourceLoader) throws Exception
    {
       //do something 
    }

    private static abstract class MyInnerClass {

        public abstract InputStream loadResource(String name);

    }
}

I want to write unit test for myPrivateMethod for which I need to pass resourceLoader object and override it's loadResource method.

Here is my test method:

@Test
public void testMyPrivateMethod() throws Exception {
    Class<?> cls = Class.forName("my.pack.MyClass$MyInnerClass");
    Method method = cls.getDeclaredMethod("loadResource", String.class);
    //create inner class instance and override method
    Whitebox.invokeMethod(myClassObject, "testValue1", "testValue2", "name1", 10, innerClassObject);
}

Note, that I can't change code.

Well, you could use Javassist ...

See this question . I haven't tried this, but you can call this method when you want the override:

public <T extends Object> T getOverride(Class<T> cls, MethodHandler handler) {
    ProxyFactory factory = new ProxyFactory();
    factory.setSuperclass(cls);
    factory.setFilter(
            new MethodFilter() {
                @Override
                public boolean isHandled(Method method) {
                    return Modifier.isAbstract(method.getModifiers());
                }
            }
        );

    return (T) factory.create(new Class<?>[0], new Object[0], handler);
}

Well, the problem i see with your code is that you are calling myPublicMethod and you are giving fourth parameter as new MyInnerClass(). Now in your private method fourth parameter is given as ResourceLoader and from your code i see no relation between MyInnerClass and ResourceLoader. So you can try out following code. It might help.

Despite your warning that you cannot change the code i have changed it because i was trying to run your code.

class MyClass{

    private static final int VERSION_VALUE = 8;

    private static final String VERSION_KEY = "versionName";

    public boolean myPublicMethod(String str) {
        try { 
            return myPrivateMethod(str, VERSION_KEY, VERSION_VALUE,
                    new MyInnerClass() {

                    @Override
            public InputStream loadResource(String name) {
                return null;
                            //do something important
                        }
                    });
        }
        catch (Exception e) {           
        }
        return false;
    }


private boolean myPrivateMethod(String str, String key, int version,
            MyInnerClass resourceLoader) throws Exception
    {
        return false;
       //do something 
    }

    private static abstract class MyInnerClass {

        public abstract InputStream loadResource(String name);

    }
}

Hope it helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM