Mocking a private constructor

Pranav Kapoor picture Pranav Kapoor · Sep 26, 2016 · Viewed 16.6k times · Source

The Site class is provided to me by an external team and has a private constructor.

public class Site
{
   int id;
   String brand;

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

The SiteUtil class (controlled by team) is

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

The data the getSite() function applies it logic on requires a network call, therefore it needs to be mocked. It doesn't have a setter currently (maybe to maintain consistency with the data source, not so sure)

I mock it as follows

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

The code above of course dosent compile as I use the public constructor. The solution I read was to mock the private constructor of Site object. I'm however at a loss on how to do that (First time writing unit tests!)

Answer

Nicolas Filotto picture Nicolas Filotto · Sep 26, 2016

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

        ...
    }
}