Intereting Posts
Андроид не работает и не появляется сообщение об ошибке Как создать приложение для Android с помощью HTML 5 Являются ли глубокие знания Java необходимым для Android? Консоль Eclipse показывает: «Не удалось нажать выделение: файловая система только для чтения», когда я пытаюсь нажать файл Unity API плагинов Google Play Services не синхронизирован с функцией пользовательского интерфейса Show Leaderboard? Проблемы с импортом классов платформы Android Android CheckBox – восстановление состояния после вращения экрана Как сохранить, экспортировать или конвертировать Android XML Drawable в качестве файла изображения PNG? Царство закрывается Использование Android RecognizerIntent с Bluetooth-гарнитурой Когда используется функция onActivityResult фрагмента в отношении жизненного цикла фрагментов? Ограничить доступ для загрузки приложения в Google Play Получить текущее местоположение 0 в marshmallow, где ниже 23 API его дать точное текущее местоположение с использованием плавленого местоположения Как читать и писать теги Android NFC? Внедрить метод startForeground в Android

Тестирование блоков Android, требующих контекста

Я пишу свой первый бэкэнд на базе Android, и я изо всех сил пытаюсь установить тест на создание моей базы данных.

В настоящее время проблема, с которой я сталкиваюсь, заключается в получении действительного объекта Context для передачи моей реализации SQLiteOpenHelper. Есть ли способ получить объект Context в классе, расширяющем TestCase? Решение, о котором я думал, заключается в создании экземпляра Activity в методе настройки моей TestCase и последующем назначении контекста этого Activity переменной поля, к которой могут обращаться мои тестовые методы … но похоже, что должен быть более простой способ.

Спасибо за ваш вклад!

Macy

Solutions Collecting From Web of "Тестирование блоков Android, требующих контекста"

Вы можете попробовать перейти на AndroidTestCase . От взгляда на документы, похоже, он должен предоставить вам действительный контекст для перехода к SQLiteOpenHelper.

Изменить: Имейте в виду, что вы, вероятно, должны настроить свои тесты в «Android Test Project» в Eclipse, поскольку тесты будут пытаться выполнить на эмуляторе (или на реальном устройстве).

Если вы используете тесты с помощью AndroidJUnit4 вы можете использовать методы InstrumentationRegistry для получения контекста:

InstrumentationRegistry.getTargetContext() – предоставляет приложение Context целевого приложения;

InstrumentationRegistry.getContext() – предоставляет Context этого пакета Instrumentation;

Использование AndroidTestCase:getContext() дает только мой контекст. Для моих тестов я использую пустую активность в своем основном приложении и получаю Context через это. Я также расширяю класс набора тестов классом ActivityInstrumentationTestCase2 . Кажется, работает на меня.

 public class DatabaseTest extends ActivityInstrumentationTestCase2<EmptyActivity> EmptyActivity activity; Context mContext = null; ... @Before public void setUp() { activity = getActivity(); mContext = activity; } ... //tests to follow } 

Что делают все остальные?

Вы должны использовать ApplicationTestCase или ServiceTestCase.

Расширение AndroidTestCase и вызов AndroidTestCase: getContext () отлично работал для меня, чтобы получить контекст и использовать его с SQLiteDatabase.

Единственное нарушение заключается в том, что создаваемая и / или используемая им база данных будет такой же, как и используемая производственным приложением, поэтому вы, вероятно, захотите использовать другое имя файла для обоих

например.

  public static final String NOTES_DB = "notestore.db"; public static final String DEBUG_NOTES_DB = "DEBUG_notestore.db"; 

Вы можете получить из MockContext и вернуть, например, MockResources на getResources() , действительный ContentResolver на getContentResolver() и т. Д. Это позволяет с некоторой болью провести некоторые модульные тесты .

Альтернативой может служить, например, Robolectric, который имитирует целую ОС Android. Это будет для системных тестов : намного медленнее работать.

Сначала создайте тестовый класс в (androidTest).

Теперь используйте следующий код:

 public class YourDBTest extends InstrumentationTestCase { private DBContracts.DatabaseHelper db; private RenamingDelegatingContext context; @Override public void setUp() throws Exception { super.setUp(); context = new RenamingDelegatingContext(getInstrumentation().getTargetContext(), "test_"); db = new DBContracts.DatabaseHelper(context); } @Override public void tearDown() throws Exception { db.close(); super.tearDown(); } @Test public void test1() throws Exception { // here is your context context = context; }} 

Альтернативное решение – избегать использования ApplicationTestCase или AndroidTestCase или любого другого класса, зависящего от Context . Дело в том, что нет необходимости проверять структуру SQLite или ORM чтобы вы могли создавать интерфейс с помощью основных методов CRUD :

 public interface UsersManager{ User createUser(String userId); User getUser(String userId); boolean updateUser(User user); boolean deleteUser(User user); } 

И реализуйте две версии: одну для тестов и другую для производственной среды исполнения. Версия для тестов может быть легко реализована с помощью HashMap :

 public class TestUsersManager implements UsersManager{ private HashMap<String, User> users = new HashMap(); public User createUser(String userId){ User result = new User(userId); users.put(userId, user); return result; } //... other methods } 

Он работает быстро (без дискового IO в случае SQLite ) и не имеет внешних зависимостей. Кстати, это также дополнительный уровень абстракции: для производственного кода вы можете легко переключаться между ORM например.