2016-06-22 3 views
2

리플렉션을 사용하여 개인 내부 클래스의 메소드를 테스트하는 방법이 있습니까? 아래의 코드에서 , 어떻게 우리가 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) { 
     // 
    } 
} 
} 
+2

"테스트 동작, 구현 아님". 이것이 개인 내부 클래스 인 경우 구현 세부 사항입니다. 클래스의 동작 (public 메서드를 통해 노출)에 대해 생각하고 테스트합니다. –

+0

이 구현 세부 사항을 테스트해야합니다. 이것은 단위 테스트입니다. – user1918858

+1

@ JaroslawPawlak의 의견과 비슷하게 특정 동작을 가장 잘 테스트하는 경우 테스트 할 수있는 공용 메서드를 사용하여이 동작을 다른 개체로 리팩토링하는 것이 좋습니다. 그런 다음 이러한 개인 메서드가있는 기존 개체는 테스트 된 공용 동작과 함께이 새 개체를 내부적으로 사용할 수 있습니다. – FishStix

답변

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

당신은 Mockito를 사용하여이 사용하는 모의 객체를 테스트 할 수있는 테스트 할 수 있습니다.

+0

Mockito를 사용하는 방법에 대한 자세한 내용을 제공해주십시오. – user1918858

+0

Mockito 웹 사이트로 이동합니다. 그것도 예제를했다. –

0

어쨌든 반영하고 setAccessible(true)을 사용하는 것이 가능하지만 개인 비 정적 내부 클래스가있는 것처럼 어렵습니다.

가장 흥미로운 질문은 왜 그렇게하고 싶습니까?

이러한 내부 클래스 및 메서드는 테스트 된 외부 클래스의 동작에 영향을 주어야합니다. 그래서 그 수업을 시험해보십시오!

클래스의 전용 부분 테스트는 테스트가 필요없는 레거시 코드가 있기 때문에에만 을 테스트하려는 경우에 주로 게으른 테스트를위한 신호입니다. 하지만 미안하지만 그건 쓸모가 없다.

  • 테스트는 화이트 박스 구현에 바인딩 테스트가 아닌 전체 동작
  • 가장 중요한 변경되지 않은 경우에도 모든 내부 리팩토링 테스트를 깰 수있는 클래스
  • 의 API입니다 : 내부 클래스 또는 개인 메서드가 올바른 방법으로 사용되는지 (또는 전혀) 테스트되지 않습니다.

전체 노력은 쓸모가 없으므로 대신 전체 수업을 테스트 해보십시오.

0

나는 이것을 처리 할 필요가 없었지만 좋은 질문이라고 생각합니다. 나는 이것에 대해 100 % 확실하지는 않지만 아마도 이것은 효과가있을 것입니다.

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

현재 테스트 할 환경이 없습니다. 하지만 아마도 도움이 될 것입니다.

관련 문제