Заглушка Mockito не работает после заглушки исключения

Итак, я пытаюсь провести модульное тестирование класса в различных сценариях. Мы используем JUnit V 4.
У меня есть метод setUp, в котором я перезагружаю макет, чтобы вернуть ожидаемое значение макета. У меня есть 4 теста: test1-test4. test1, test2 отлично работают с ожидаемым фиктивным значением, настроенным в методе perTestSetup.

Для теста t3 требуется MockClass, чтобы генерировать исключение, поэтому я настраиваю его отдельно в t3. Теперь t3 работает нормально, поскольку макет генерирует исключение, как и ожидалось.

Но когда perTestSetup пытается сбросить макет, чтобы вернуть mockResult перед запуском test4, он терпит неудачу и выдает то же исключение времени выполнения, настроенное в t4. Я также пробовал reset (), прежде чем издеваться над perTestSetup (). Но и это тоже терпит неудачу.

Что мне здесь не хватает?

@Before
public void perTestSetup(){ 
    when(MockClass.functionCall(...)).thenReturn(mockResult);
}

@Test
public void test1(){
}

@Test
public void test2(){
}

@Test
public void test3(){
    when(MockClass.functionCall(...)).thenThrow(new RuntimeExcption());
    ...
}

@Test
public void test4(){
}

person nikel    schedule 18.10.2020    source источник


Ответы (1)


Ваш метод perTestSetup () не делает то, что вы думаете. Аннотация @Before означает, что тестовая среда будет запускать этот метод один раз перед выполнением любого из тестов, а не один раз за тест. Прежде чем я закончил читать ваш вопрос, мне действительно не терпелось посоветовать вам переименовать этот метод в просто setup (), так как это было бы более точное описание.

Параметры:

  1. Измените аннотацию на @BeforeEach, что затем изменит поведение, чтобы делать то, что, по вашему мнению, он должен делать в данный момент. Однако это было бы неэффективно, так как во вторых двух тестах вы будете определять поведение, а затем сразу же его переопределять.

  2. Как выглядят параметры в вашей functionCall (...)? В одном методе @Before setup () можно определить два разных поведения, т.е.

when(MockClass.functionCall(good values)).thenReturn(mockResult);
when(MockClass.functionCall(bad values)).thenThrow(new RuntimeException());

В каждом тесте вызывайте functionCall () с соответствующими значениями для этого конкретного теста.

  1. Если параметры в functionCall () не подходят для предыдущего подхода, рассмотрите возможность создания двух отдельных экземпляров MockClass, например
MockClass successfulMockClass = new mock(MockClass.class);
when(successfulMockClass()).thenReturn(mockResult);
MockClass unsuccessfulMockClass = new mock(MockClass.class);
when(unsuccessfulMockClass()).thenThrow(new RuntimeException());

В своих тестах вызывайте соответствующий имитируемый объект в зависимости от того, с какими входными данными вы тестируете.

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

person sunrise    schedule 18.10.2020
comment
Я добавил строку журнала в perTestSetup (), которая проверяет его выполнение перед каждым тестом. Итак, это предположение верно: stackoverflow .com / questions / 20295578 ​​/ 2. Параметры, к сожалению, такие же. 3. Класс используется в контексте DI, поэтому создание отдельных моков кажется излишним. Не может использовать много кода в качестве своей организации. Конкретный: - |. Если я не получу ответов, конвертирую его в общий кусок. - person nikel; 19.10.2020