反思:如何覆盖私有静态抽象内部类方法



我有以下类:

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);
    }
}

我想为myPrivateMethod编写单元测试,为此我需要传递resourceLoader对象并覆盖它的loadResource方法。

这是我的测试方法:

@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);
}

注意,我不能更改代码。

好吧,你可以使用Javassist。。。

请参阅此问题。我还没有尝试过,但当你想要覆盖时,你可以调用这个方法:

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);
}

好吧,我在代码中看到的问题是,您正在调用myPublicMethod,并将第四个参数作为新的MyInnerClass((。现在,在您的私有方法中,第四个参数被指定为ResourceLoader,从您的代码中,我看不到MyInnerClass和ResourceLoader之间的关系。所以您可以尝试以下代码。这可能会有所帮助。

尽管你警告说你不能更改代码,但我已经更改了它,因为我试图运行你的代码。

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);
    }
}

希望能有所帮助。

相关内容

  • 没有找到相关文章

最新更新