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

How to provide object inside public method to access another method within it using 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 提供给 class 中的 provideData 方法?

你也要嘲笑WeatherDataSingleton.getInstance().getApiWeatherData()

如果您一般不使用静态访问,尤其是 Singelton 模式,这会容易得多。


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

  1. 创建 WeatherDataSingleton 的模拟。
  2. 配置您的测试以便使用此模拟(通过正确使用 依赖注入 或通过使用 Powermock 投降到您的糟糕设计)。
  3. 将模拟配置为 return 数据:

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

这解决了 NPE。

如果您对生产代码应用简单的重构,我认为您不需要使用 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();
}

然后在您的测试中期望新方法 return 特定对象:

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