Search code examples
unit-testingjunit4powermockito

Mocking a final class variable


I am trying to test a class in which a final instance of class in used. I am not getting how to create a mock of this final object(in our example foo). After a lot of dig around I started using powermockito and whenNew method. I am not sure if I am doing it correctly or not as I am new to JUnits. After looking at this I changed the @PrepareForTest to Sample.class(earlier it was Foo.class) and after that both foo and koo are coming null.

Class Foo

public class Foo{
  void hello(){
  }
}

Class Sample

public class Sample{
  private final Foo foo= new Foo();
  private Koo koo = new Koo();
  String run(){
    String strr = koo.something();
    return foo.hello();
  }
}

Test Class

@RunWith(PowerMockRunner.class)
@PrepareWith({Sample.class})
public class SampleTest{
  @InjectMocks
  private Sample sample;

  @Mock
  private Koo koo;

  @Test
  void run(){
    Foo foo = PowerMockito.mock(Foo.class);
    PowerMockito.whenNew(Foo.class).withNoArguments.thenReturn(foo);

    when(koo.something()).thenReturn("abc");
    when(foo.hello()).thenReturn("def");
    String check = sample.run();
    assertEquals("abc", check);
  }
}

Solution

  • foo is an instance variable that will be initialized when Sample class is instantiated. If you want to mock this instance variable using whenNew then it should happen while the Sample class is loaded before the test method is executed.

    @RunWith(PowerMockRunner.class)
    @PrepareForTest({ Sample.class })
    public class SampleTest {
    
      @InjectMocks
      private Sample sample;
    
      @BeforeClass 
      public static void setUp() throws Exception {
    
        Foo foo = PowerMockito.mock(Foo.class);
        Mockito.when(foo.hello()).thenReturn("def");
        PowerMockito.whenNew(Foo.class).withNoArguments().thenReturn(foo);
      }
    
      @Test
      public void run() throws Exception {
    
        String check = sample.run();
        Assert.assertEquals("def", check);
      }
    }