如何使用PowerMock在public方法中提供对象来访问其中的另一个方法?

时间:2017-03-16 16:36:13

标签: java unit-testing junit mockito powermock

我正在编写一个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) {....}

我想只使用power mock的verify方法来测试populateWeatherData是否被执行。以下是我到目前为止的测试用例。

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

如果我运行这个,我在

的provideData方法中得到空指针异常
if(null != apiWeatherData.getCurrently()){

如何在该类中提供apiWeatherData来提供data方法?

2 个答案:

答案 0 :(得分:1)

你也必须模仿WeatherDataSingleton.getInstance().getApiWeatherData()

如果您不使用静态访问,特别是Singelton模式,这会更容易。

  

我试过嘲笑它,但是我应该如何将该模拟对象提供给provideData()?

  1. 创建WeatherDataSingleton的模拟。
  2. 配置您的测试以便使用此模拟(通过正确使用依赖注入或使用Powermock放弃您的错误设计)。
  3. 配置mock以返回数据:

    doReturn(currentlyPojo).when(weatherDataSingletonMock).getApiWeatherData();
    
  4. 这解决了NPE。

答案 1 :(得分:1)

如果您将简单的重构应用于生产代码,我认为您不需要使用PowerMockito:

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

然后在你的测试中期望新方法返回某个对象:

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