Модульные тесты Android, требующие контекста - PullRequest
57 голосов
/ 19 января 2010

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

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

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

Мэйси

Ответы [ 9 ]

40 голосов
/ 19 января 2010

Вы можете попробовать переключиться на AndroidTestCase .При просмотре документации кажется, что она сможет предоставить вам действительный контекст для передачи в SQLiteOpenHelper.

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

26 голосов
/ 20 мая 2016

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

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

InstrumentationRegistry.getContext() - предоставляет Context пакета данного инструментария.


Для AndroidX используйте InstrumentationRegistry.getInstrumentation().getTargetContext() или InstrumentationRegistry.getInstrumentation().getContext().

5 голосов
/ 20 августа 2012

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

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

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

3 голосов
/ 04 июня 2015

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

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

3 голосов
/ 20 января 2010

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

2 голосов
/ 04 мая 2013

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

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

, например.

  public static final String    NOTES_DB      = "notestore.db";
  public  static final String   DEBUG_NOTES_DB = "DEBUG_notestore.db";
0 голосов
/ 09 июня 2019

Ваш тест не является модульным тестом !!!

Когда вам нужно

  • Контекст
  • Чтение или запись на хранение
  • Сеть доступа
  • Или измените любую конфигурацию для проверки вашей функции

Вы не пишете юнит-тест.

Вам нужно написать свой тест в androidTest пакете

0 голосов
/ 12 сентября 2016

Первый создать тестовый класс в (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;
}}
0 голосов
/ 04 февраля 2016

Альтернативное решение состоит в том, чтобы избежать использования 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 фреймворками, например.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...