2012-08-07 70 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; 
     } 
    } 
} 

在這種情況下,我想檢查localInstance對象,因爲它是由privateHelperToIntercept()呼叫消耗。

我發現很多例子來模擬私人方法調用; PowerMock的expectPrivate(partiallyMockedObject, "nameOfPrivateMethod", arg1, arg2)效果很好。我還找到了攔截​​傳遞給公共方法調用的參數的例子; Capture<Type> myTestCapture = new Capture<Type>()加上someMockedObject.PublicMethod(capture(myTestCapture))

不幸的是,我既不能讓兩者一起工作,也找不到將它們組合的例子。有沒有人看到一種方法來做到這一點?

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 2012-08-20 14:56:26

+0

我喜歡這個主意,但不幸的是這不是一個選項。 「Program」類示例是產品代碼,現在不是通過該類提取新的ArbitraryTypes的好時機。 – Ben 2012-09-25 18:59:18

相關問題