Java Mockito: как подготовить разные ответы

int calledCnt = 0;
doAnswer(i -> {
    if (calledCnt == 0) {
        calledCnt += 1;
        throw new InternalServerErrorException("test");
    }
    return false;
}).when(myClass.someFunction(any()));

Я хочу заглушить вызов, где, если он был вызван изначально, возникнет исключение, но любые последующие вызовы вернут false;

вышеуказанный вызов жалуется "Variables used in lambda should be final or effectively final"


person ealeon    schedule 19.06.2019    source источник


Ответы (2)


Либо сделайте calledCnt чем-то изменяемым (например, int[] с одним элементом или AtomicInteger), либо объявите ответ как анонимный класс, чтобы вы могли добавить переменную-член:

doAnswer(new Answer<Boolean>() {
  int calledCnt = 0;

  @Object public Boolean answer(InvocationOnMock invocation) {
    if (calledCnt == 0) {
      calledCnt += 1;
      throw new InternalServerErrorException("test");
    }
    return false;
  }
}).when(...);

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

person Andy Turner    schedule 20.06.2019

В зависимости от того, является ли myClass тем, что вы тестируете, или зависимостью, я бы рекомендовал полностью или частично имитировать myClass (т.е., по крайней мере, вызов someFunction()). Используя методы then...(), вы можете указать серию возвращаемых элементов, например:

when(myMockedClass.someFunction(any()))
    .thenThrow(new InternalServerErrorException("test"))
    .thenReturn(false);

первый вызов вызовет исключение, а второй вызов и все последующие вызовы вернут false.

person MyStackRunnethOver    schedule 20.06.2019