简体   繁体   中英

Mockito - Impossible stubbing mocked object

I am newbie in Java world, but it is very hard understand why not can I stub method of a mocked object...

@RunWith(MockitoJUnitRunner.class)
public class ChildBLLIT extends BaseInteractorIT {

  @InjectMocks
  private ChildBLL ChildBLL = Mockito.mock(ChildBLL.class);

  @Before
  public void setUp() {
    ChildBLL.engine = engineMock;
  }

  /**
   * Test of getZipStatistics method, of class ChildBLL.
   */
  @Test
  public void testGetZipStatistics() {
    final String testZipStatisticsText = "DummyZipStatistics";
    //This method will throw the null pointer exception
   when(ChildBLL.engine.getZIPStatistics()).thenReturn(testZipStatisticsText);


    ChildBLL.getZipStatistics();
    verify(ChildBLL.engine).getZIPStatistics();
  }

}

When I try to stub the getZIPStatistics() method I get always a null pointer exception, of course I get, because in the getZIPStatistics() method there is an private object, which is not mocked... it seems to me the Mockito does not mocking the private fields... and unfortunately this is from another project:

public class BaseIT {

  @Mock
  protected static FromOtherProject engineMock;

  @Before
  public void initMocks() {
    MockitoAnnotations.initMocks(this);
  }  
}

Here I mocked the engine variable, but then how can I mock/stub the getZIPStatistics() method? This is this method:

public class FromOtherProject {
    //...
    public final String getZIPStatistics() {
        return ZIPStatistics.toString();
    }
}

What can I do?

Let's assume a simple class...

public class Account {

    public String getPassword() {
        return "abc";
    }
}

...and simple class that contains it...

public class AccountHolder {
    private Account account;

    public String getAccountPassword() {
         return this.account.getPassword();
    }

}

So now we have a simple base class for all Account based tests...

public class AccountBasedTest {

   @Mock
   protected Account account;

}

...and a class that actually tests the AccountHolder...

@RunWith(MockitoJUnitRunner.class)
public class AccountHolderTest extends AccountBasedTest {

    @InjectMocks
    private AccountHolder accountHolder;

    @Test
    public void getAccountPasswort_must_return_account_password() {
         Mockito.when( this.account.getPassword() ).thenReturn ("xyz");

         Assert.assertEquals("xyz", this.accountHolder.getAccountPassword());
    }

}

And that's all. The @InjectMocks, etc. annotations will also look in the superclasses, so you get your mocked account and that account will be put into your AccountHolder. No need to call MockitoAnnotations.initMocks . It shouldn't hurt, but it's not needed because you are using the MockitoJUnitRunner already, which does exactly that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM