web-dev-qa-db-ja.com

プライベートコンストラクターをあざける

Siteクラスは外部チームから提供され、privateコンストラクターがあります。

_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);
_

もちろん、上記のコードは、パブリックコンストラクターを使用するときにコンパイルされます。私が読んだ解決策は、Siteオブジェクトのプライベートコンストラクターをモックすることでした。しかし、私はそれを行う方法に迷っています(初めてユニットテストを書く!)

6
Pranav Kapoor

コードがゲッターを介してのみidbrandの値にアクセスすると仮定すると、クラスSiteをモックし、静的メソッドSiteUtil.getSite() as next:

// Use the launcher of powermock
@RunWith(PowerMockRunner.class)
public class MyTestClass {

    @Test
    // Prepare the class for which we want to mock a static method
    @PrepareForTest(SiteUtil.class)
    public void myTest() throws Exception{
        // Build the mock of Site
        Site mockSite = PowerMockito.mock(Site.class);
        // Define the return values of the getters of our mock
        PowerMockito.when(mockSite.getId()).thenReturn(1);
        PowerMockito.when(mockSite.getBrand()).thenReturn("Google");
        // We use spy as we only want to mock one specific method otherwise
        // to mock all static methods use mockStatic instead
        PowerMockito.spy(SiteUtil.class);
        // Define the return value of our static method
        PowerMockito.when(SiteUtil.getSite()).thenReturn(mockSite);

        ...
    }
}
6
Nicolas Filotto

別のアプローチとして、経営陣に支援を求めることができれば、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;
    }
}

このように、テストのために、独自の(モックされた)戦略を注入できますが、コードの既存のクライアントを変更する必要はありません。 (これには、ルックアップ自体をそのグループでテストしやすくするという利点もあります。)

1