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
オブジェクトのプライベートコンストラクターをモックすることでした。しかし、私はそれを行う方法に迷っています(初めてユニットテストを書く!)
コードがゲッターを介してのみid
とbrand
の値にアクセスすると仮定すると、クラス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);
...
}
}
別のアプローチとして、経営陣に支援を求めることができれば、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;
}
}
このように、テストのために、独自の(モックされた)戦略を注入できますが、コードの既存のクライアントを変更する必要はありません。 (これには、ルックアップ自体をそのグループでテストしやすくするという利点もあります。)