2015-02-22 2 views
3

У меня есть один класс контроллера, который обрабатывает создание фрагмента. Скажем, как показано ниже:Как издеваться над методом Bundle в Android-тесте Android?

public class FragmentController { 

    public static Fragment newInstance(String title, int total) { 
     return total > 0? MultipleDataFragment.newInstance(title, total) 
      : SingleDataFragment.newInstance(title); 
    } 
} 
public class MultipleDataFragment extends Fragment { 
    public static MultipleDataFragment newInstance(String title, int total) { 
     Bundle b = new Bundle(); 
     b.putString("title", title); 
     b.putInt("total", total); 
    } 
} 
public class SingleDataFragment extends Fragment { 
    public static SingleDataFragment newInstance(String title, int total) { 
     Bundle b = new Bundle(); 
     b.putString("title", title); 
     b.putInt("total", total); 
    } 
} 

В моем тесте (стандартный Junit4 тест класс) у меня есть:

@Test 
public void testNewInstanceCreteMultipleData() throws Exception { 
    Fragment f = FragmentController.newInstance("Hello", 5); 

    assertTrue("MultipleDataFragment should be created" 
     , f instanceOf MultipleDataFragment); 
} 

Поскольку я не дразнить Пакет, я получаю.

java.lang.RuntimeException: Method putString not mocked.Set 

Вопрос в том, как я издеваюсь над объектом Bundle, чтобы тест мог быть выполнен? Нужен ли мне статический метод внутри каждого класса, который создает объект Bundle, и использовать его вместо этого или есть лучший подход к этому?

Любой пример этому оценили.

+0

Обратите внимание, что методы getInstance() неполны. У них даже нет обратных заявлений. –

ответ

5

Одним из способов может быть использование мощной насмешливой структуры, такой как PowerMock, которая может даже перехватывать строительство новых объектов.

Это должно работать для вас, но насмешливые «простые» классы, такие как Bundle, означают некоторое усилие - вы также можете использовать реальную реализацию, используя UnMock plugin.

+1

Для примера макета класса Bundle вы можете проверить [мой ответ на очень похожий вопрос] (http://stackoverflow.com/a/38700186/976883). Что касается UnMock, мне не удалось использовать его с Bundle, так как я получил «NoSuchFieldError» для «mMap» при запуске упрощенного тестового примера. –

+0

Начиная с API 21, Bundle расширяет BaseBundle, поэтому он не может найти mMap. К сожалению, unmocking BaseBundle не помогает, потому что ArrayMap теперь использует нестандартную версию System.arraycopy(), которую JVM не содержит. Так что unmocking Bundle не работает. –

+0

@ErikBrowne Каково ваше решение? – Huteri

0

Используйте Unmock plugin, чтобы разучить класс Bundle. Вам нужно будет высмеять с Android 4.4 (unmock 'org.robolectric:android-all:4.4_r1-robolectric-1'), так как более поздние версии ссылок на Android используют нестандартные Java-методы.

Вам также необходимо сохранить ArrayMap и MapCollections.

Смежные вопросы