2016-09-26 107 views
3

Site課程由外部團隊提供給我,並有一個專用構造函數。嘲笑私人構造函數

public class Site 
{ 
    int id; 
    String brand; 

    private Site(int id, String brand) 
    { 
     this.id = id; 
     this.brand = brand; 
    } 
} 

的SiteUtil類(由隊控制)是

public class SiteUtil 
{ 
    public static Site getSite() 
    { 
    Site site; 
    //Logic 
    return site; 
    } 
} 

數據的getSite()函數應用它邏輯上需要一個網絡的呼叫,因此它需要被模擬。它沒有一個二傳手當前(可能保持與數據源,不那麼肯定一致性)

我嘲笑它,如下所示

Site mockSite = new Site(1,"Google"); 
PowerMockito.when(SiteUtil.getSite(1)).thenReturn(mockSite); 

以上課程的代碼編譯dosent我用公構造函數。 我讀的解決方案是模擬Site對象的私有構造函數。但是我就如何做一個損失

+0

您可以使用java反射訪問私有。 – Tokazio

+0

你能詳細說明一下我可以看的代碼或參考嗎? –

+0

Ouch。這是一個糟糕的API設計。組織中的「外部團隊」是完全獨立的嗎? – chrylis

回答

3

這裏是你如何能繼續假設,只有通過你的干將代碼訪問的idbrand值(第一次寫單元測試!):

@RunWith(PowerMockRunner.class) 
public class MyTestClass { 

    @Test 
    @PrepareForTest(SiteUtil.class) 
    public void myTest() throws Exception{ 
     Site mockSite = PowerMockito.mock(Site.class); 
     PowerMockito.when(mockSite.getId()).thenReturn(1); 
     PowerMockito.when(mockSite.getBrand()).thenReturn("Google"); 
     PowerMockito.spy(SiteUtil.class); 
     PowerMockito.when(SiteUtil.getSite()).thenReturn(mockSite); 

     ... 
    } 
} 
1

作爲一種替代方法,如果您可以讓管理層支持您,則可以通過兼容方式更改其API。而是隱藏在網絡查找在getSite()方法,外部化它們放入一個SiteLookupStrategy

public class SiteUtil { 
    private static SiteLookupStrategy strategy = new DefaultSiteLookupStrategy(); 

    public static Site getSite(int siteNum) { 
     return strategy.lookup(siteNum); 
    } 

    public static void setLookupStrategy(SiteLookupStrategy strategy) { 
     SiteUtil.strategy = strategy; 
    } 
} 

這種方式,進行測試,你可以注入自己的(嘲笑)戰略,但是代碼的現有客戶將不需要被改變。 (這也有使查找本身更易於測試該組的優點。)