The Site
class is provided to me by an external team and has a private constructor.
public class Site
{
int id;
String br
As an alternate approach, there's a way to compatibly alter their API if you can get management to back you. Instead of hiding the network lookups in the getSite()
method, externalize them into a 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;
}
}
This way, for testing, you could inject your own (mocked) strategy, but existing clients of the code would not need to be changed. (This also has the advantage of making the lookup itself easier to test for that group.)
Assuming that your code accesses to the value of id
and brand
only through getters, you could simply mock your class Site
then return this mock when you call the static method 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);
...
}
}