2015-09-22 1 views
1

Я нахожусь в процессе миграции robolectric 3.0robolectric 3,0 Mockito - как издеваются класс внутри деятельности

Проблема Statement--

У меня есть класс AppUtility, который конкретизируется в MyActivity, поэтому для проверки его методов вызывается, мне нужно издеваться над ним в своем тесте перед настройкой MyActivity.

Вот мой код:

@Mock 
private AppUtility mockAppUtility; 

@Before 
public void setUp() { 
    initMocks(this); 
    myActivity= Robolectric.setupActivity(MyActivity.class); 
    equalsButton = (Button) myActivity.findViewById(R.id.equals_sign); 
    shadowActivity = Shadows.shadowOf(myActivity); 
} 

Вот метод испытания: -

@Test 
     public void shouldCallStartAlarm() { 
      for (int i = 0; i < 4; i++) { 
       equalsButton.performClick(); 
      } 
      verify(mockAppUtility).startAlarm(); 
     } 

Bu Я получаю следующее сообщение об ошибке Сообщ: - которые показывают макет не связан с деятельностью , как я могу привязать его к активности?

Actually, there were zero interactions with this mock. 

Но макет объекта не связан с тестом. С ранней версии Robolectric я использую, чтобы связать фиктивный объект по созданию деятельности, путем переопределения его, как показано ниже

myActivity = new MyActivity() { 
       @Override 
       AppUtility getUtil() { 
        return mockAppUtility; 
       } 
      }; 
      myActivity.onCreate(new Bundle()); 

и использовать для работы в порядке, с Robolectric 3.0, как я могу связать фиктивный объект перед началом деятельности ,

После @nenick вашего второго варианта: Вот как это выглядит

@Mock 
    private AppUtility appUtility; 
    @InjectMocks 
    private MyActivity myActivity; 
    @Before 
    public void setUp() { 
     ActivityController<MyActivity> activityController = Robolectric.buildActivity(MyActivity.class); 
//  myActivity= Robolectric.setupActivity(MyActivity.class); 
     myActivity=activityController.get(); 
     initMocks(this); 
     activityController.setup(); 
     equalsButton = (Button) myActivity.findViewById(R.id.equals_sign); 
//  shadowActivity = Shadows.shadowOf(calculatorActivity); 
    } 

но я получаю fllowing исключения: -

java.lang.IllegalArgumentException: attempted to invoke public final android.app.Application org.robolectric.shadows.ShadowActivity.getApplication() on instance of class org.com.android.AppUtility$$EnhancerByMockitoWithCGLIB$$77c74666, but AppUtility$$EnhancerByMockitoWithCGLIB$$77c74666 doesn't extend ShadowActivity 

он ломает на этапе - activityController.setup() ;

ответ

4

Просто установить макет с помощью функции mockito mock injection.

@Mock 
private AppUtility mockAppUtility; 

@InjectMocks 
Activity mActivity; 

@Before 
public void setUp() { 
    myActivity= Robolectric.setupActivity(MyActivity.class); 
    equalsButton = (Button) myActivity.findViewById(R.id.equals_sign); 
    shadowActivity = Shadows.shadowOf(myActivity); 

    // create and injects mocks into object annotated with @InjectMocks 
    initMocks(this); 
} 

Чтобы установить mocks перед настройкой активности (onCreate, ...), вы должны получить доступ к своей активности перед настройкой.

@Before 
public void setUp() { 
    ActivityController<Activity> activityController = Robolectric.buildActivity(Activity.class); 

    // get the activity instance 
    mActivity = activityController.get() 

    initMocks(this); 

    // now setup your activity after mock injection 
    activityController.setup() 
} 
+0

Я обновляю это в своем вопросе, он выглядит неуклюжим здесь. –

+0

Спасибо @nenick, ложная функция впрыска была действительно полезной. –

+0

Вы устранили исключение IllegalArgumentException? Mockito является агрессивным и заменяет свойство __robo_data__. – nenick

0

Одно из основных правил модульного тестирования - никогда не издевайтесь над классом под тестом. Вы можете использовать spy, но снова это вызов спасения, который вы не должны использовать в этом случае.

Другой smell, показывающий, что у вас есть тест на пробуждение - когда вы сможете успешно выполнить эти тесты, это не гарантирует, что установлен настоящий будильник. Это гарантирует только то, что этот метод был вызван. Поэтому лучше проверить арифмы, а не проверять вызов метода. Проверьте this link для примера использования диспетчера теневой тревоги

+0

метод startAlarm() в настоящее время относится к диспетчеру сигналов тревоги android. Оператор проблемы: - как только кнопка равенства нажата четыре раза, метод startAlarm() должен получить вызов. Поэтому мне нужно проверить иск Mockito, независимо от того, вызвано это или нет. Как я могу высмеять класс полезности внутри деятельности, любую идею? –

+0

'UtilityClass' звучит как вызов статического метода. Верный? Если это так, вы можете обернуть его в нестационарный контекст и высмеять его под тестом.Как я уже упоминал, вы все еще не можете проверить подлинный экземпляр класса –

+0

извините, но его даже не статические вызовы методов. На самом деле, я создаю экземпляр класса в активности (имя UtilityClass - это просто ссылка на проблему в stackoverflow). –