Рубрики
Без рубрики

Разница между тем, когда () и doXxx () Методы в Mockito

Узнайте преимущества и недостатки настройки макет объекта, когда ().thenXxx() или doXxx ()., когда () образом.

Автор оригинала: Attila Fejér.

1. Введение

Mockito является популярным Java насмешливый рамки. С его помощью легко создавать макеты объектов, настраивать макет поведения, захватывать аргументы метода и проверять взаимодействие с макетами.

Теперь мы сосредоточимся на указании макетного поведения. У нас есть два способа сделать это: когда ().тогда Что-то () и doSomething ()., когда () синтаксис.

В этом коротком учебнике, мы увидим, почему у нас есть оба из них.

2. когда () Метод

Рассмотрим следующее Сотрудник интерфейс:

interface Employee {
    String greet();
    void work(DayOfWeek day);
}

В наших тестах мы используем макет этого интерфейса. Допустим, мы хотим настроить макет приветствовать () метод возврата строки “Здравствуйте” . Это просто сделать с помощью программного когда () метод:

@Test
void givenNonVoidMethod_callingWhen_shouldConfigureBehavior() {
    // given
    when(employee.greet()).thenReturn("Hello");

    // when
    String greeting = employee.greet();

    // then
    assertThat(greeting, is("Hello"));
}

Что происходит? сотрудник объект является макетом. Когда мы называем любой из его методов, Mockito регистрирует этот вызов. С призывом когда () метод, Mockito знает, что этот призыв не был взаимодействия бизнес-логики. Это было заявление, которое мы хотим назначить некоторое поведение макет объекта. После этого, с одним из thenXxx () методы, мы указать ожидаемое поведение.

До этого момента, это старые добрые насмешки. Кроме того, мы хотим настроить работа () метод, чтобы бросить исключение, когда мы называем его с аргументом воскресенье:

@Test
void givenVoidMethod_callingWhen_wontCompile() {
    // given
    when(employee.work(DayOfWeek.SUNDAY)).thenThrow(new IAmOnHolidayException());

    // when
    Executable workCall = () -> employee.work(DayOfWeek.SUNDAY);

    // then
    assertThrows(IAmOnHolidayException.class, workCall);
}

К сожалению, этот код не будет компилироваться, потому что в работа (employee.work(…)) вызова, работа () метод имеет недействительными тип возврата; следовательно, мы не можем обернуть его в другой вызов метода. Означает ли это, что мы не можем издеваться над недействительными методами? Конечно, можем. doXxx методы спасения!

3. doXxx() Методы

Давайте посмотрим, как мы можем настроить исключение бросали с doThrow () метод:

@Test
void givenVoidMethod_callingDoThrow_shouldConfigureBehavior() {
    // given
    doThrow(new IAmOnHolidayException()).when(employee).work(DayOfWeek.SUNDAY);

    // when
    Executable workCall = () -> employee.work(DayOfWeek.SUNDAY);

    // then
    assertThrows(IAmOnHolidayException.class, workCall);
}

Этот синтаксис немного отличается от предыдущего: мы не пытаемся обернуть недействительными вызов метода внутри другого вызова метода. Таким образом, этот код компилирует.

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

Обратите внимание, что это не то же самое когда () метод, который мы использовали раньше. Кроме того, обратите внимание, что мы приковали макет взаимодействия после вызова когда (). Между тем, мы определил его внутри скобки с первым синтаксисом.

Почему у нас первый когда ().thenXxx() , когда он не способен на такую общую задачу, как настройка недействительными вызов? Он имеет несколько преимуществ для doXxx ()., когда () синтаксис.

Во-первых, разработчикам логичнее писать и читать заявления типа «когда какое-то взаимодействие, то что-то делать», чем «делать что-то, когда какое-то взаимодействие».

Во-вторых, мы можем добавить несколько поведений к одному и тому же взаимодействию с цепочками. Это потому, что когда () возвращает экземпляр класса OngoingStubbing , который является thenXxx() методы возвращают тот же тип.

С другой стороны, doXxx () методы возвращают Стаббер например, и Stubber.when (T макет) возвращает T , таким образом, мы можем указать, какой метод вызова мы хотим настроить. Но T является частью нашего приложения, например, Сотрудник в наших фрагментах кода. Но T не вернет класс Mockito, поэтому мы не сможем добавить несколько поведений с цепочками.

4. БДДМОКИТО

BDDMockito использует альтернативный синтаксис для тех, которые мы рассмотрели. Это довольно просто: в наших макет конфигураций, мы должны заменить ключевое слово ” когда” к ” учитывая ” и ключевое слово ” делать ” к ” будет “. Помимо этого, наш код остается прежним:

@Test
void givenNonVoidMethod_callingGiven_shouldConfigureBehavior() {
    // given
    given(employee.greet()).willReturn("Hello");

    // when
    String greeting = employee.greet();

    // then
    assertThat(greeting, is("Hello"));
}

@Test
void givenVoidMethod_callingWillThrow_shouldConfigureBehavior() {
    // given
    willThrow(new IAmOnHolidayException()).given(employee).work(DayOfWeek.SUNDAY);

    // when
    Executable workCall = () -> employee.work(DayOfWeek.SUNDAY);

    // then
    assertThrows(IAmOnHolidayException.class, workCall);
}

5. Заключение

Мы увидели преимущества и недостатки настройки макет объекта когда ().thenXxx() или doXxx ()., когда () способ. Кроме того, мы видели, как эти синтаксисы работают и почему у нас есть и то, и другое.

Как обычно, примеры доступны более на GitHub .