2013-08-29 56 views
3

如何模擬修改私有變量的私有方法?如何模擬修改私有變量的私有方法?

class SomeClass{ 
    private int one; 
    private int second; 

    public SomeClass(){} 

    public int calculateSomething(){ 
     complexInitialization(); 
     return this.one + this.second; 
    } 

    private void complexInitialization(){ 
     one = ... 
     second = ... 
    } 
} 

回答

0

功率模擬可能會幫助你在這裏。但通常我會使該方法受到保護,並重寫以前私有的方法來完成我想要的操作。

2

假如其他答案指出這樣的測試用例很脆弱,並且測試用例不應該基於實現,並且應該依賴於行爲,如果您仍然想要嘲笑它們,那麼這裏有一些方法:

PrivateMethodDemo tested = createPartialMock(PrivateMethodDemo.class, 
           "sayIt", String.class); 
String expected = "Hello altered World"; 
expectPrivate(tested, "sayIt", "name").andReturn(expected); 
replay(tested); 
String actual = tested.say("name"); 
verify(tested); 
assertEquals("Expected and actual did not match", expected, actual); 

這是你如何使用PowerMock來做到這一點。

PowerMock的expectPrivate()做到這一點。

Test cases from PowerMock其測試私有方法嘲諷

UPDATE: Partial Mocking with PowerMock有一些免責條款,並抓住

class CustomerService { 

    public void add(Customer customer) { 
     if (someCondition) { 
      subscribeToNewsletter(customer); 
     } 
    } 

    void subscribeToNewsletter(Customer customer) { 
     // ...subscribing stuff 
    } 
} 

然後創建的CustomerService的部分模擬,讓你想方法列表嘲笑。

CustomerService customerService = PowerMock.createPartialMock(CustomerService.class, "subscribeToNewsletter"); 
customerService.subscribeToNewsletter(anyObject(Customer.class)); 

replayAll(); 

customerService.add(createMock(Customer.class)); 

向客服模擬中那麼add()是要測試和subscribeToNewsletter()你現在可以寫一個期望像往常一樣的方法,真實的東西。

+0

你嘲笑私有方法,_returns_結果,而不是修改** **內部領域。 – Cherry

+0

櫻桃檢查更新的答案。 –

8

您不需要,因爲您的測試將取決於正在測試的類的實現細節,因此會變得很脆弱。你可以重構你的代碼,使得你當前正在測試的類依賴另一個對象來完成這個計算。然後你可以嘲笑這個被測試類的依賴。或者你將實現細節留給類本身,並充分測試它的可觀察行爲。

你可以從遭受的問題是,你是不是完全分離的命令和查詢類。 calculateSomething看起來更像是一個查詢,但complexInitialization更像是一個命令。

+0

第一段的最後一句是正確的答案。測試需要基於_behaviour_,而不是圍繞實施。看看各種答案(包括我的)到非常類似的問題,在http://stackoverflow.com/questions/18435092/how-to-unit-test-a-private-variable/18435828#18435828 –