почему метод шпиона нельзя заглушить?

Интересно, можно ли заглушить шпиона, созданного Mockito, чтобы вернуть значение. В следующем коде spy.get(0) заглушен, чтобы вернуть недостижимую строку. Поэтому я думаю, что assertEquals() следует передать. Но тестовый метод заканчивается выдачей исключения IndexOutOfBoundsException. Итак, я думаю, что должна быть вызвана настоящая версия get(), а не заглушенная версия. Можно ли заглушить шпиона?

@Test
public void doReturnUsage() throws Exception {
    List<String> list = new ArrayList<String>();
    List<String> spy = spy(list);
    when(spy.get(0)).thenReturn("not reachable");
    assertEquals("not reachable", spy.get(0));
}

person Parmenides    schedule 15.11.2018    source источник
comment
Ваш пример и то, как его исправить, буквально в документации: static.javadoc.io/org.mockito/mockito-core/2.23.0/org/mockito/   -  person JB Nizet    schedule 15.11.2018


Ответы (2)


Когда вы используете @Spy, синтаксис немного отличается от обычного экземпляра Injected.

Mockito.doReturn("not reachable").when(spy).get(0);

Шпионить так же полезно, когда вы хотите «издеваться» над общедоступным методом, который находится в классе, который вы тестируете. например

Class A {
  public void methodA() {
    // do something
  }
  public void methodB() {
    // do something 
    call methodA();
   // do something else 
  }
}

Здесь открытый метод «methodA» класса A вызывается из открытого метода «methodB». Поэтому при написании тестового примера для «methodB» мы имитируем вызов «methodA», используя spy. И мы самостоятельно тестируем "метод А"

person lrathod    schedule 18.11.2018
comment
Спасибо за ответ. Но я понятия не имею, почему мы должны использовать doReturn(), а не thenReturn(). IMO, doReturn() используется для заглушки метода void. Метод get() вовсе не является методом void. - person Parmenides; 23.11.2018
comment
когда вы используете шпион, это синтаксис, которому мы должны следовать. то есть doReturn против thenReturn. И doNothing() используется для заглушки метода void. - person lrathod; 24.11.2018
comment
Как я могу решить, когда использовать doReturn, когда использовать thenReturn? - person Parmenides; 24.11.2018
comment
size() можно заглушить: when(spy.size()).thenReturn(100); - person Parmenides; 24.11.2018
comment
Заглушка get(0) вызовет исключение: when(spy.get(0)).thenReturn(good); - person Parmenides; 24.11.2018

Рассмотрим другой пример:

@Test
public void thenReturnUsage() {
    List<String> list = new LinkedList<String>();
    List<String> spy = spy(list);
    // doReturn(100).when(spy).size(); 
    when(spy.size()).thenReturn(100);
    int size = spy.size();
    assertEquals(100, size);
}

Этот тест проходит снова. Но spy.size() заглушен с помощью when().thenReturn(), а не doReturn().when(). Почему?

person Parmenides    schedule 23.11.2018