Внедрение зависимостей в многопроцессорных приложениях Android

TLDR: я разрабатываю приложение, которое работает в нескольких процессах. В целях тестирования пользовательского интерфейса я хочу внедрить поддельную зависимость API, чтобы приложение, работающее в тестах, не зависело от сетевых взаимодействий, однако в многопроцессорном режиме это, похоже, не работает.

Я использую подход, описанный в этом посте, поэтому я реализовал кастом AndroidJUnitRunner который создает приложение с фиктивными зависимостями (пусть будет MockApplicationвместо того, чтобы с реальными зависимостями (пусть будет RealApplication). Это работает, и мое приложение запрашивает интерфейс поддельного API из основного процесса.

Мое приложение, однако, использует несколько процессов, например, есть обработка данных Service который работает в своем собственном процессе и который только начинается startService вызов из кода приложения. По какой-то причине этот процесс выполняется с экземпляром RealApplication, без каких-либо ложных зависимостей.

Можно ли как-нибудь заставить это работать? Я пробовал копаться в коде Android, отвечающем за создание экземпляров приложения, но пока не нашел ничего особенно полезного.

PS Я использую Dagger 2 для DI, но это, вероятно, не очень актуально.

2 ответа

Проблема в том, что ваш пользовательский класс приложения не переопределяет реальный класс в AndroidManifest.xml,

Вы просто указываете инструментальному тестировщику запустить свой пользовательский класс приложения, но затем, если приложение запускает другой процесс, Android Framework даже не узнает, что ему нужно запустить собственный пользовательский класс приложения вместо реального.

Итак, я бы посоветовал вам переопределить класс приложения в пользовательский класс в AndroidManifest.xml в течение connectedAndroid выполнение задачи, в результате ваше приложение будет использовать пользовательский класс, даже не взламывая тестировщика и всякий раз, когда запускаются новые процессы.

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

Чтобы использовать пользовательский объект приложения (MockApplication) в каждом процессе вашего приложения во время тестов, решение состоит в том, чтобы внедрить переменную сборки в ваш процесс. AndroidManifest.xml с помощью manifestPlaceholder.

Я определил два вида продукта в build.gradle:

productFlavors {
    mock {
        manifestPlaceholders = [application:".MockApplication"]
    }
    prod {
        manifestPlaceholders = [application:".RealApplication"]
    }

}
  • prod: установит реальный объект Application (RealApplication) в манифест
  • mock: установит объект приложения Mock (MockApplication) для имитации сетевых вызовов

В AndroidManifest.xmlиспользуйте переменную application как это:

<application 
    android:label="@string/app_name"
    android:name="${application}">

Теперь, когда вы хотите использовать MockApplication, просто запустите тестирование инструментов с вариантом сборки "mockDebug"

Другие вопросы по тегам