Тесты андроид: заглушка для Ретрофита с Mockito


В моем MainActivity есть метод под названием getAPI, который возвращает OTBServiceWrapper. Это используется для настройки retrofit для вызова API.

В моем файле MainActivityTest я пытаюсь заглушить вызов new OTBService().getService(), который делает метод getApi, чтобы я мог вернуть MockedOTBService, который изменяет клиента на пользовательский, который возвращает json.

Как есть, текущая реализация будет это MockedOTBService, если я должен был поместить регистратор в MockedOTBService, но также проваливается и вызывает реальный api, который не хочу я хочу в испытании.

Я пытаюсь заглушить вызовы API Retrofit с помощью Mockito и return json. Я, кажется, не могу понять, почему заглушка вызывается, но не заглушает метод, о котором идет речь.

Примечания:

  1. я использую ActivityInstrumentationTestCase2
  2. я провожу только один тест
  3. Если я добавлю verify(mockedOTBService, atLeastOnce()).getService();, это говорит, что он никогда не вызывался.
  4. Если я изменяю when...thenReturn на использование mMainActivity = spy(getActivity()), то изменения не происходит и вызывается реальный API.

Logcat Вывод

Logger﹕ MockedOTBService was called // Mock is called
Logger﹕ Real OTBService was called // Real API is called
Logger﹕ MainActivity getAPI method class is "$Proxy1" // Mock is shown in MainActivity
Logger﹕ RealAPIResponse JSON Parsed ID: 266 // Real API response returned

Реальный Поток

Основная активность.onCreate () > OTBService.getService () > OTBServiceWrapper.createSearch(...)

Попытка достичь в рамках тестов

Основная активность.onCreate () > MockedOTBService.getService () > OTBServiceWrapper.createSearch(...)

Основная активность.java

public class MainActivity extends Activity {
  private OTBServiceWrapper serviceWrapper;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    getApi().createSearch(...)
  }

  public OTBServiceWrapper getApi() {
    return new OTBService().getService();
  }
}

Отбсервис.java

public class OTBService {
  public OTBServiceWrapper getService() {
    RestAdapter restAdapter = new RestAdapter.Builder()
        .setEndpoint(Constants.API_URL)
        .build();

    return restAdapter.create(OTBServiceWrapper.class);
  }
}

OTBServiceWrapper.java

public interface OTBServiceWrapper {
  @POST(Constants.API_SEARCHES_POST_URL)
  void createSearch(@Body Request request, Callback<Request.Response> callback);
}

MainActivityTest.Ява

public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
  private OTBService mMockedOTBService;
  private MainActivity mMainActivity;
  private View mSearchButton;

  public MainActivityTest() { super(MainActivity.class); }

  @Override
  protected void setUp() throws Exception {
    super.setUp();

    setActivityInitialTouchMode(true);

    System.setProperty("dexmaker.dexcache", getInstrumentation().getTargetContext().getCacheDir().getPath());

    mMockedOTBService = mock(OTBService.class);
    when(mMockedOTBService.getService()).thenReturn(new MockedOTBService(getInstrumentation().getContext()).getService());

    mMainActivity = getActivity();

    mSearchButton = mMainActivity.findViewById(R.id.AbSearchButton);
    mYourHolidayButton = mMainActivity.findViewById(R.id.AbYourHolidayButton);
  }

  public void testButtonActions() {
    TouchUtils.clickView(this, mSearchButton);
    ...
  }
}

MockedOTBService.java

public class MockedOTBService {
  private Context context;

  public MockedOTBService(Context context) { this.context = context; }

  public OTBServiceWrapper getService() {
    RestAdapter restAdapter;

    restAdapter = new RestAdapter.Builder()
        .setClient(new LocalJsonClient(context))
        .setEndpoint(Constants.API_TEST_URL)
        .build();

    return restAdapter.create(OTBServiceWrapper.class);
  }
}

LocalJsonClient.java

@SuppressLint("DefaultLocale")
public class LocalJsonClient implements Client { ... }

Строй.gradle

dependencies {
    androidTestCompile 'com.google.dexmaker:dexmaker:1.0'
    androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.0'
}
1 8

1 ответ:

Устраните необходимость издеваться над вашим запросом, разрешив действию установить сервис.

В вашем MainActivity Создайте переменную класса и задатчик класса для службы. Это должно быть a в области видимости класса, чтобы предотвратить вызов метода OnCreate до того, как вы настроите службу на то, что вы хотите, чтобы она была. Кроме того, создайте экземпляр getter, который устанавливает службу, если вы еще не сделали этого.

В тесте перед вызовом getActivity() Установите сервис в качестве вашего макета сервиса. (Может быть, подумать о перемещение его к объекту поддержки).

Основная активность.java

public class MainActivity extends Activity {
  private static OTBServiceWrapper serviceWrapper;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    getServiceWrapper.createSearch(...)
  }

  public OTBServiceWrapper getServiceWrapper() {
    if (serviceWrapper == null) {
      MainActivity.setServiceWrapper(new OTBService().getService());
    }

    return serviceWrapper;
  }

  public static void setServiceWrapper(OTBServiceWrapper serviceWrapper) {
    MainActivity.serviceWrapper = serviceWrapper;
  }
}

MainActivityTest.java

public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
  private MainActivity mMainActivity;

  public MainActivityTest() { super(MainActivity.class); }

  @Override
  protected void setUp() throws Exception {
    super.setUp();

    setActivityInitialTouchMode(true);

    MainActivity.setServiceWrapper(
      new MockedOTBService(getInstrumentation().getContext()).getService()
    );

    mMainActivity = getActivity();
  }
}