簡體   English   中英

使用反射測試內部私有類的方法

[英]Using reflection to test methods of inner private class

有沒有一種方法可以使用反射來測試私有內部類的方法? 在下面的代碼中,我們如何測試func-1和func-2

public class Outer extends AbstractOuter {
private final Properties properties;

public Outer(Properties properties) {
    this.properties = properties;
}

private class Inner extends AbstractInner {

    private int numOfProperties;

    @Override
    void func-1() throws Exception {
        //
    }

    private int func-2(long l)  {
        //
    }
}
}
package SalesUnitsIntoCarton.mySolution;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class UtilityReflections {
    private static final Object[] EMPTY = {};

    /**
     * This method returns a value, returned by the method of a private inner class, of a given object instance.
     *
     * @param outerClassInstance This parameter needs to be an instance of the outer class that contains the private inner class.
     * @param attributeNameOfInnerClassInOuterClass This is the name of the attribute that is an inner class type, within the outer class.
     * @param innerClassName This is the class name of the inner class.
     * @param methodNameOfInnerClass This is the name of the method inside the inner class that should be called.
     * @return Returns the value returned by the method of the inner class. CAUTION: needs casting since its of type {@link Object}
     * 
     * @throws SecurityException 
     * @throws NoSuchFieldException 
     * @throws ClassNotFoundException 
     * @throws NoSuchMethodException 
     * @throws InvocationTargetException 
     * @throws IllegalArgumentException 
     * @throws IllegalAccessException 
     * @throws Exception
     */
     public static <T extends Object> Object executeInnerClassMethod(T outerClassInstance, String attributeNameOfInnerClassInOuterClass, String innerClassName, String methodNameOfInnerClass) 
         throws NoSuchFieldException, SecurityException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException,
         IllegalArgumentException, InvocationTargetException {

         final Class<?> outerClass = outerClassInstance.getClass();

         final Field field = outerClass.getDeclaredField(attributeNameOfInnerClassInOuterClass);
         field.setAccessible(true);

         Class<?> innerClass = Class.forName(innerClassName);
         innerClass = field.getType();

         //access the method
         final Method method = innerClass.getDeclaredMethod(methodName, new Class<?>[]{});
         method.setAccessible(true);
         return method.invoke(field.get(outerClassInstance), EMPTY);
     }
}

通過反射和使用setAccessible(true)可以實現某種方式,但是特別是當您擁有私有的非靜態內部類時,這將很難。

最有趣的問題是: 為什么要這么做呢?

這些內部類和方法應該影響所測試的外部類的行為。 因此,請測試該課程!

嘗試測試類的私有部分通常是懶惰測試的信號,因為您可能需要較少的設置,您有沒有測試的舊代碼,並且只想測試我的更改 但是抱歉,這沒用。

  • 您的測試是綁定到實現的白盒測試,而不是類的api
  • 即使整體行為不變,任何內部重構都可能破壞測試
  • 最重要的是:您不會測試內部類或私有方法是否以正確的方式使用(或根本不使用)。

這樣做的全部努力是沒有用的,而是測試整個課程!

我沒有處理這個問題,但是我認為這是一個很好的問題。 我對此不是100%的把握,但是也許可以。

        Outer.class.getDeclaredClasses()[0].getDeclaredMethod("func-1").invoke(null);

我目前沒有環境可以測試。 但也許有幫助。

您可以使用Mockito使用模擬對象對此進行測試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM