2012-08-07 2 views
2

공용 메서드 호출의 경우 EasyMock의 capture()를 사용하면 & 메서드에 전달 된 인수를 검사 할 수 있습니다. 개인 메서드 호출의 경우 PowerMock의 expectPrivate를 사용하여 개인 메서드 호출을 모의 공격 할 수 있습니다.EasyMock 및 PowerMock으로 개인 메서드 인수 캡처

어떻게 든 이들을 결합하여 개인 메서드 호출에 전달 된 인수를 얻을 수 있습니까? 예 :이 경우

public class Program 
{ 
    public FancyReturnType PublicMethod() 
    { 
     ArbitraryType localInstance = new ArbitraryType(); 
     localInstance.setFoo(somePrivateHelperMethod()); 
     localInstance.setBar(increasinglyComplexMagic()); 

     long aLongValue = 11235L; 
     // more variables, more work 

     SomeType worker = privateHelperToIntercept(localInstance, aLongValue, otherVariables); 

     if (worker.something) 
     { 
      return retVal.aFancyReturnType; 
     } 
     else 
     { 
      return retVal.anotherFancyReturnType; 
     } 
    } 
} 

, 나는 그것이 privateHelperToIntercept() 호출에 의해 소비로 localInstance 개체를 검사 할.

개인 메소드 호출을 조롱하는 예제가 많이 있습니다. PowerMock의 expectPrivate(partiallyMockedObject, "nameOfPrivateMethod", arg1, arg2)이 효과적입니다. 공용 메서드 호출에 전달 된 인수를 가로 채기위한 예제도 발견했습니다. someMockedObject.PublicMethod(capture(myTestCapture))과 결합한 Capture<Type> myTestCapture = new Capture<Type>()

불행히도, 나는 둘이 함께 일할 수없고 그들을 결합하는 예도 찾을 수 없습니다. 아무도 이것을 할 길을 보지 못했습니까?

FWIW, 나는 Mockito가 이것을 할 수 있다고 생각하지만 소스/빌드/테스트 시스템에는 포함되어 있지 않습니다. 가능하다면 우리 시스템에서 새로운 라이브러리를 지원하는 과정을 피하고 싶습니다.

답변

1

localInstance에 대한 참조를 얻는 방법을 묻는다면 다음 코드 만 있으면됩니다.

@PrepareForTest(Program.class) 
public class Test { 
    @Test 
    public void testMethod() { 
     ArbitraryType passedLocalInstance = new ArbitraryType(); 
     PowerMock.expectNew(ArbitraryType.class).andReturn(passedLocalInstance); 

     //remainder of the test method 

     assertEquals(14.2, passedLocalInstance .getValue()); 
    } 
} 

java는 참조로 전달되므로 passedLocalInstance는 메소드 호출로 전달되는 인수가됩니다. 그 질문에 대답 했습니까?

0

new은 단순히 정적 방법입니다. 같은 방식으로 처리하십시오 ... 메소드에서 랩핑하고 메소드를 완성하십시오. 이 경우 테스트에서 모의 ​​객체를 반환하려는 경우 해당 객체와의 모든 상호 작용을 테스트 할 수 있습니다 (작성중인 객체 내의 코드에 대한 테스트의 종속성은 자체 테스트가 있어야 함)

당신의 제약 조건을 감안할 때 테스트에서

public Program { 

    // your above code up to object creation 
    ArbitraryType localInstance = createArbitraryType(); 
    // rest of your above code here 


    ArbitraryType createArbitraryType() { 
    return new ArbitraryType(); 
    } 
} 
...

public class MyTest { 
    TestableProgram extends Program { 
    @Override 
    ArbitraryType createArbitraryType() { 
     return this.arbitraryTypeMock; 
    } 
    } 

    private ArbitraryType arbitraryTypeMock; 
    private TestableMyClass objectToTest = new TestableProgram(); 

    // rest of your tests... 

} 

은 내가 그것을 할 거라고 방법입니다.

제약 조건을 약간 구부릴 수 있다면 개인적인 방법을 좀 느슨하게 할 수 있습니다. 일반적으로 테스트를 더 쉽게하기 위해 패키지 기본값을 개인적으로 사용하지 않았습니다. 귀하의 패키지에있는 사람들이 오해한다면, 그것은 대개 귀하의 코드이므로 사적인 것은 대부분 당신에게서 어쨌든 보호하고 있습니다. (하지만 나는 그 질문에 대한 올바른 답변이 아니라는 것을 알고 있습니다 ...).

+0

Bueler? ... Bueler? – Gus

+0

나는 그 생각이 마음에 들지만, 불행히도 그 선택은 아니었다. "프로그램"클래스 샘플은 제품 코드 였으므로 해당 클래스를 통해 새로운 ArbitraryTypes를 추출하는 것은 좋지 않습니다. – Ben