2016-09-26 15 views
3

Siteクラスは外部チームによって私に提供され、プライベートコンストラクタを持ちます。プライベートコンストラクタの模擬

public class Site 
{ 
    int id; 
    String brand; 

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

(チームによって制御される)SiteUtilクラスは、getSite()関数はそれを上にロジックを適用

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

データであり、従って、それは嘲笑される必要がある、ネットワーク呼び出しを必要とします。それは

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

もちろん上記のコードは、私が公共を使用してコンパイルdosentを次のように

私はそれを嘲笑(多分、そうわからないデータソースとの整合性を維持するために)現在セッターを持っていませんコンストラクタ。 私が読んだ解決策は、Siteオブジェクトのプライベートコンストラクタをモックすることでした。私はそれを行う方法についての損失で、しかしだ

+0

Javaリフレクションで秘密鍵にアクセスできます。 – Tokazio

+0

私が見ることができるいくつかのコードやリファレンスを詳しく説明できますか? –

+0

これはひどいAPIデザインです。あなたの組織内の「外部チーム」か、完全に別個のチームですか? – chrylis

答えて

3

ここであなただけのゲッターによるidbrandの値にあなたのコードへのアクセスのことを仮定して進めることができるか(第1時間書き込みユニットテストを!):

@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

もう1つの方法として、管理者からの返品を得ることができれば、互換性のあるAPIを変更する方法があります。

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; 
    } 
} 

この方法では、テストのために、あなたがあなた自身の(嘲笑)戦略を注入できますが、コードの既存のクライアントはする必要はありません。代わりにgetSite()方法でネットワーク検索を隠す、SiteLookupStrategyにそれらを外部化変更する。 (これはまた、そのグループのためのルックアップそのものをテストしやすくする利点があります)。