Вопрос по java – @RunWith (MockitoJUnitRunner.class) против MockitoAnnotations.initMocks (это)

92

Во время написания нового теста jUnit4 мне интересно, стоит ли использовать@RunWith(MockitoJUnitRunner.class)  или жеMockitoAnnotations.initMocks(this).

Я создал новый тест & amp; мастер автоматически сгенерировал тест с Runner. В Javadocs для MockitoJUnitRunner говорится следующее:

Compatible with JUnit 4.4 and higher, this runner adds following behavior:

Initializes mocks annotated with Mock, so that explicit usage of MockitoAnnotations.initMocks(Object) is not necessary. Mocks are initialized before each test method. validates framework usage after each test method.

Мне не ясно, имеет ли использование Runner какое-либо преимущество передinitMocks() метод, который я использовал в прошлом.

Любые мысли или ссылки будут оценены!

Ваш Ответ

2   ответа
110

MockitoJUnitRunner дает вам автоматическую проверку использования фреймворка, а также автоматическуюinitMocks().

Автоматическая проверка использования фреймворка действительно стоит того. Это даст вам лучшую отчетность, если вы сделаете одну из этих ошибок.

Вы называете статичнымwhen метод, но не заканчивайте заглушку соответствующимthenReturn, thenThrow илиthen. (Ошибка 1 в приведенном ниже коде)

Ты звонишьverify на макете, но не забудьте предоставить вызов метода, который вы пытаетесь проверить. (Ошибка 2 в коде ниже)

Вы называетеwhen метод послеdoReturn, doThrow илиdoAnswer и передайте имитацию, но не забудьте указать метод, который вы пытаетесь заглушить. (Ошибка 3 в коде ниже)

Если у вас нет подтверждения использования фреймворка, об этих ошибках не сообщается доследующи вызов метода Мокито. Это может быть

в том же методе тестирования (как ошибка 1 ниже), в следующем методе тестирования (как ошибка 2 ниже), в следующем тестовом классе.

Если они происходят в последнем тесте, который вы запускаете (как ошибка 3 ниже), о них вообще не будет сообщено.

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

@Test
public void test1() {

    // ERROR 1
    // This compiles and runs, but it's an invalid use of the framework because 
    // Mockito is still waiting to find out what it should do when myMethod is called.
    // But Mockito can't report it yet, because the call to thenReturn might 
    // be yet to happen.
    when(myMock.method1());

    doSomeTestingStuff();

    // ERROR 1 is reported on the following line, even though it's not the line with
    // the error.
    verify(myMock).method2();

}

@Test
public void test2() {

    doSomeTestingStuff();

    // ERROR 2
    // This compiles and runs, but it's an invalid use of the framework because
    // Mockito doesn't know what method call to verify.  But Mockito can't report 
    // it yet, because the call to the method that's being verified might 
    // be yet to happen.
    verify(myMock);
}

@Test
public void test3() {

    // ERROR 2 is reported on the following line, even though it's not even in 
    // the same test as the error.
    doReturn("Hello").when(myMock).method1();


    // ERROR 3
    // This compiles and runs, but it's an invalid use of the framework because
    // Mockito doesn't know what method call is being stubbed.  But Mockito can't 
    // report it yet, because the call to the method that's being stubbed might 
    // be yet to happen.

    doReturn("World").when(myMock);

    ,doSomeTestingStuff(); 

    //  ERROR 3 is never reported, because there are no more Mockito calls. 
}

Теперь, когда я впервые написал этот ответ более пяти лет назад, я написал

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

Моя рекомендация изменилась. Команда Mockito добавила новую функцию, так как я впервые написал этот ответ. Это правило JUnit, которое выполняет ту же функцию, что иMockitoJUnitRunner. Но это лучше, потому что это не исключает использование других бегунов.

Включаю

@Rule 
public MockitoRule rule = MockitoJUnit.rule();

в вашем тестовом классе. Это инициализирует макеты и автоматизирует проверку структуры; какMockitoJUnitRunner делает. Но теперь вы можете использоватьSpringJUnit4ClassRunner или любой другой JUnitRunner. Начиная с Mockito 2.1.0, есть дополнительные опции, которые точно контролируют, о каких проблемах сообщают.

Смотриjavadocs дляMockito.validateMockitoUsage() для получения дополнительной информации об этой проверке. avandeursen
Я точно не могу сказать, что они одинаковы. в одном тестовом случае установка junit runner не удалась и не внедрила мои mocks должным образом, если я не выполнил установку initMocks dtc
@ yuranos87 Звучит как то, что вы должны задать как новый вопрос. Не забывайте включать свой код, когда вы это делаете - бессмысленно спрашивать «почему этот код делает XYZ», если вы не показываете код. Dawood ibn Kareem
@ DavidWallace, вот и ты: / Stackoverflow.com вопросы / 41045467 / ... yuranos87
Мы используем testng 6.8.8 + mockito 1.10.19 и, очевидно, мы не можем использовать MockitoJUnitRunner, но среда валидации все еще работает! И это работает точно так же, как @ Дэвид Уоллес. Может кто-нибудь объяснить? Это потому, что у нас все еще есть обратные вызовы @ Before * и MockitoAnnotations.initMocks (this)? yuranos87
23

ходимости для@Before метод). С другой стороны, использование бегуна иногда невозможно, т. Е. Когда вы его уже используете, например,SpringJUnit4ClassRunner.

Это оно. Это просто вопрос предпочтений.

Кроме строки initMocks (), метод @Before по-прежнему нужен для любой другой настройки, верно? OceanBlue
@ OceanBlue: Конечно, если ваш@Before метод содержал все, кромеinitMocks() чем вы должны сохранить его после перехода на бегун. Tomasz Nurkiewicz
твет Дэвида Уоллеса о проверке фреймворка полностью отвечает на мой вопрос, поэтому я принял его, но +1 за то, что указал, что этот бегун не может быть использован с другим, как Spring. Благодарность OceanBlue
Я использую Spring Boot и могу сказать, чтоSpringJUnit4ClassRunner автоматически инициализирует макеты для меня. Я не знаю насчет простой весны. gustavohenke

Похожие вопросы