Перезапуск приложения на Android-тесте

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

SDK должен быть инициализирован только один раз за экземпляр приложения, иначе он вызовет RuntimeError. Так что на стороне приложения в классе Application должно быть что-то вроде этого:

public class SampleApplication extends Application { @Override public void onCreate() { super.onCreate(); //Here I can do something that will change the default configs //Here I initialize the SDK singleton method Sdk.initialize(); } } 

Реализация sdk abstract:

 public class Sdk { private static SampleApplication sInstance; private void Sdk(){ } public static SampleApplication getInstance() throws RuntimeException { if (sInstance == null) { throw new RuntimeException(); } return sInstance; } public static void initialize() { if (sInstance == null) { sInstance = new Sdk(); //save some information according to what is on the default configurations } else { throw new RuntimeException("Method was already initialized"); } } } 

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

Поэтому я создал Android-тест, который расширяет ApplicationTest

ApplicationTest:

  public class ApplicationTest extends ApplicationTestCase<SampleApplication> { public ApplicationTest() { super(SampleApplication.class); } } 

Образец теста Android:

 public class SampleTest extends ApplicationTest { @Override protected void setUp() throws Exception { // Here I restart the user preferences although I need to restart the application // terminateApplication(); // createApplication(); super.setUp(); } @Override protected void tearDown() throws Exception { super.tearDown(); } public void testDefaultSettings() { // Here is where I want to restart application input // some values on the user preferences settings in order // to test the output on sharedpreferences by the initialized method } } 

Я попытался закончить и создать приложение снова, но без успеха. Мой вопрос: можно ли перезапустить приложение Android-теста? Я здесь что-то не так?

Я полагаю, проблема, с которой вы действительно сталкиваетесь, – это проблема InstrumentationTestRunner : как запретить ActivityUnitTestCase вызывать Application.onCreate? (И, по-видимому, нет очевидного решения)

Т.е. TestRunner будет вызывать onCreate() во время его инициализации в любом случае, поэтому, как только вы вызываете createApplication() , ваш Sdk уже инициализирован.

Что касается самого вопроса, я считаю, единственный вариант – переосмыслить архитектуру класса Sdk (или добавить некоторую функцию «сброса» и т. Д.),

 public class TestApplication extends Application { @Override public void onCreate() { super.onCreate(); // Sdk.terminate(); - If you specify TestApplication as an // application class in AndroidManifest, // you'll have to uncomment this(due to issue with test runner) Sdk.initialize(); } @Override public void onTerminate() { super.onTerminate(); Sdk.terminate(); } } 

Класс Sdk

 public class Sdk { private static Sdk sInstance; private void Sdk(){ } public static Sdk getInstance() throws RuntimeException { if (sInstance == null) { throw new RuntimeException(); } return sInstance; } public static void terminate() { sInstance = null; } public static void initialize() { if (sInstance == null) { sInstance = new Sdk(); //save some information according to what is on the default configurations } else { throw new RuntimeException("Method was already initialized"); } } } 

тесты:

 public class MyApplicationTest extends ApplicationTestCase<TestApplication> { public MyApplicationTest() { super(TestApplication.class); } public void testMultiplicationTests() { createApplication(); int answer = 42; assertEquals(42, answer); terminateApplication(); } public void testDefaultSettings() { createApplication(); assertNotNull(Sdk.getInstance()); terminateApplication(); } } 

NB! Вы можете сделать его немного менее приятным, если вы примените специальный AndroidManifest для androidTest. Затем вы не будете бороться с проблемой TestRunner, когда он сам вызовет функцию Create (), прежде чем начнутся тесты.

Я надеюсь, что это помогает