0

I am writing unit test case for a Class

public class CurrentMoreInfoDataProvider implements CurrentMoreInfoInterface.presenterToModel{

private CurrentMoreInfoInterface.modelToPresenter modelToPresenter;

public CurrentMoreInfoDataProvider(CurrentMoreInfoInterface.modelToPresenter modelToPresenter) {
    this.modelToPresenter = modelToPresenter;
}

@Override
public void provideData() {
    WeatherApiResponsePojo apiWeatherData = WeatherDataSingleton.getInstance().getApiWeatherData();
    if(null != apiWeatherData.getCurrently()){
        CurrentlyPojo currently = apiWeatherData.getCurrently();
        if(null != currently){
            populateWeatherData(currently);
        }
    }
}

public void populateWeatherData(CurrentlyPojo currently) {....}

I want to just use verify method of power mock to test whether populateWeatherData get executed or not. Below is my test case so far.

@RunWith(PowerMockRunner.class)
@PrepareForTest(CurrentMoreInfoDataProvider.class)
public class TestCurrentMoreInfoDataProvider {

    private CurrentMoreInfoDataProvider dataProvider;
    @Mock
    CurrentMoreInfoInterface.modelToPresenter modelToPresenter;

    private CurrentlyPojo currentlyPojo = new CurrentlyPojo();
    @Test
    public void testPopulateWeatherData(){

        dataProvider = PowerMockito.spy(new CurrentMoreInfoDataProvider(modelToPresenter));
        dataProvider.provideData();
        Mockito.verify(dataProvider).populateWeatherData(currentlyPojo);
    }
}

If I run this I get null pointer exception in provideData method at

if(null != apiWeatherData.getCurrently()){

How should I provide apiWeatherData to provideData method in that class?

Swapnil Kadam
  • 4,075
  • 5
  • 29
  • 35
  • See [here](http://stackoverflow.com/questions/10583202/powermockito-mock-single-static-method-and-return-object) to mock a static method. – Andrew S Mar 16 '17 at 16:40

2 Answers2

1

You have to mock WeatherDataSingleton.getInstance().getApiWeatherData() too.

This would be much easier if you would not use static access in general and the Singelton pattern in particular.


I tried mocking it, but how should i provide that mock object to provideData() ?

  1. create a mock of WeatherDataSingleton.
  2. Configure your Test so that this mock is used (by properly using dependency injection or by surrendering to your bad design using Powermock).
  3. configure the mock to return the data:

    doReturn(currentlyPojo).when(weatherDataSingletonMock).getApiWeatherData();
    

This resolves the NPE.

Timothy Truckle
  • 15,071
  • 2
  • 27
  • 51
1

I dont think you need to go for PowerMockito if you apply a simple refactor to your production code:

public class CurrentMoreInfoDataProvider{

@Override
public void provideData() {
    WeatherApiResponsePojo apiWeatherData = getApiWeatherData();
    if(null != apiWeatherData.getCurrently()){
        CurrentlyPojo currently = apiWeatherData.getCurrently();
        if(null != currently){
            populateWeatherData(currently);
        }
    }
}

WeatherApiResponsePojo getApiWeatherData(){
   return WeatherDataSingleton.getInstance().getApiWeatherData();
}

then in your test expect that new method to return certain object:

@RunWith(MockitoJUnitRunner.class)
public class TestCurrentMoreInfoDataProvider {


    private CurrentMoreInfoDataProvider dataProvider;
    @Mock
    CurrentMoreInfoInterface.modelToPresenter modelToPresenter;
    @Mock
    WeatherApiResponsePojo apiWeatherDataMock;

    private CurrentlyPojo currentlyPojo = new CurrentlyPojo();
    @Test
    public void testPopulateWeatherData(){

        dataProvider = PowerMockito.spy(new CurrentMoreInfoDataProvider(modelToPresenter));

        doReturn(apiWeatherDataMock).when(dataProvider).getApiWeatherData();

        dataProvider.provideData();
        Mockito.verify(dataProvider).populateWeatherData(currentlyPojo);
    }
}
Maciej Kowalski
  • 25,605
  • 12
  • 54
  • 63
  • Thanks for your reply. I get following error Wanted but not invoked: currentMoreInfoDataProvider.populateWeatherData( – Swapnil Kadam Mar 16 '17 at 16:51
  • You have tell mockito what it should return when apiWeatherData.getCurrently() method is called. ApiWeatherData is a mock so just use when().thenReturn() to specify that – Maciej Kowalski Mar 16 '17 at 16:54
  • When I attempted first I did get the same error so to solve this I referred to https://groups.google.com/forum/#!topic/powermock/CEdP24sb_HY – Swapnil Kadam Mar 16 '17 at 16:54