Вопрос

В настоящее время я нахожусь в процессе использования Mockito, чтобы издеваться над своими объектами сервисного уровня в приложении Spring MVC, в котором я хочу проверить свои методы контроллера. Однако, как я читал о специфике Mockito, я обнаружил, что методы doReturn(...).when(...) эквивалентно when(...).thenReturn(...). Анкет Итак, мой вопрос в том, в чем смысл иметь два метода, которые делают одно и то же или какова тонкая разница между doReturn(...).when(...) а также when(...).thenReturn(...)?

Любая помощь будет оценена.

Это было полезно?

Решение

Два синтаксиса для загрязнения примерно эквивалентны. Однако вы можете всегда использовать doReturn/when для загрязнения; Но есть случаи, когда вы не мочь использовать when/thenReturn. Анкет Загрязняние пустого методов - это один из них. Другие включают в себя использование с шпионами Макета и загрязняние того же метода более одного раза.

Одна вещь when/thenReturn дает вам, что doReturn/when Не является проверкой типов значения, которое вы возвращаете, во время компиляции. Тем не менее, я считаю, что это почти не имеет значения - если у вас неправильный тип, вы узнаете, как только вы запустите свой тест.

Я настоятельно рекомендую только использовать doReturn/when. Анкет Нет смысла изучать два синтаксиса, когда это сделает.

Вы можете обратиться к моему ответу в Формирование Mockito "грамматики" - Более подробный ответ на очень тесно связанный вопрос.

Другие советы

Оба подхода ведут себя по -разному, если вы используете шпионевый объект (аннотированный с @Spy) вместо макета (аннотированный с @Mock):

  • when(...) thenReturn(...) делает реальный вызов метода Непосредственно перед тем, как указанное значение будет возвращено. Поэтому, если вызываемый метод бросает исключение, вам приходится иметь дело с ним / издеваться над ним и т. Д., Конечно, вы все равно получите свой результат (что вы определяете в thenReturn(...))

  • doReturn(...) when(...) вообще не вызывает метод.

Пример:

public class MyClass {
     protected String methodToBeTested() {
           return anotherMethodInClass();
     }

     protected String anotherMethodInClass() {
          throw new NullPointerException();
     }
}

Тест:

@Spy
private MyClass myClass;

// ...

// would work fine
doReturn("test").when(myClass).anotherMethodInClass();

// would throw a NullPointerException
when(myClass.anotherMethodInClass()).thenReturn("test");

Mockito Javadoc, кажется, говорит, почему использует doReturn() вместо when()Используйте doreturn () в тех редких случаях, когда вы не можете использовать Mockito.when (Object).

Остерегайтесь того, что Mockito.When (Object) всегда рекомендуется для загрязнения, потому что он является безопасным и более читаемым (особенно при закреплении последовательных вызовов).

Вот те редкие случаи, когда Doreturn () пригодится:

1. При шпионаже реальных объектов и вызова реальных методов на шпионе приносят побочные эффекты

List list = new LinkedList(); List spy = spy(list);

// невозможно: реальный метод называется так spy.get (0) бросает indexoutofboundsexception (список еще пуст)

when(spy.get(0)).thenReturn("foo");

// Вы должны использовать doreturn () для загрязнения: doReturn("foo").when(spy).get(0);

2. Переоценивая предыдущее количество исключений:

when(mock.foo()).thenThrow(new RuntimeException());

// невозможно: метод Foo (), заполненный исключением, называется так, чтобы Runtimeexception брошено. when(mock.foo()).thenReturn("bar");

// Вы должны использовать doreturn () для загрязнения:

doReturn("bar").when(mock).foo(); Выше сценарии показывают компромисс элегантного синтаксиса Мокето. Обратите внимание, что сценарии очень редки. Шпионаж должен быть спорадическим, а перевидение исключений очень редко. Не говоря уже о том, что в целом переопределение загрязнения является потенциальным запахом кода, который указывает на слишком много загрязнения.

Продолжение этот ответ, Есть еще одна разница в том, что если вы хотите, чтобы ваш метод возвращал разные значения, например, когда он в первый раз вызывается, второй раз называется и т. Д., Вы можете передавать значения так, например ...

PowerMockito.doReturn(false, false, true).when(SomeClass.class, "SomeMethod", Matchers.any(SomeClass.class));

Таким образом, он вернется false, когда метод будет вызван в том же тестовом примере, а затем снова вернется false и, наконец, правда.

Последняя альтернатива используется для методов макетов, которые возвращаются void.

Посмотрите, например, здесь:Как сделать издевательство с пустыми методами с Mockito

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top