Использование MockitoJUnitRunner.class вместо SpringJUnit4ClassRunner.class

У меня вопрос об использовании SpringJUnit4ClassRunner. Для чистых приложений Junits или Unit Test мы должны использовать аннотации на основе Spring, такие как @Autowired, вместе с SpringJUnit4ClassRunner или использовать вместо этого MockitoJUnitRunner вместо аннотации @RunWith в верхней части тестового класса?

Я имею в виду замену

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({ "classpath:test-applicationContext.xml" })

с просто

@RunWith(MockitoJUnitRunner.class)

в верхней части класса. Это работает для меня.

В Junits мы обычно не делаем никаких внешних вызовов, таких как звонки в БД или вызов какой-либо другой веб-службы. Мы должны издеваться над этими внешними вызовами, используя аннотации @Mock для этих объектов службы. А затем создайте реальный объект класса, который мы тестируем, и это зависит от этих макетов. Затем мы можем использовать @InjectMocks на реальном объекте так, чтобы он вводился с издеваемыми объектами.

Пример Service-A- > Calls- > Service-B- > Calls- > Service-C

Во время тестирования A мы должны посмеяться над сервисом B и при тестировании Service-B мы должны высмеять Service-C.

Некоторые фрагменты кода

@RunWith(MockitoJUnitRunner.class)
public class TestServiceA {
    @Mock
    B mockObj;

    @InjectMocks
    A realObj;

    @Test
    public void testServiceA() {
    .....
    .....
    }
}       

Итак, я считаю, что для случаев Unit Test нам не нужно полагаться на контейнер Spring, чтобы предоставить нам экземпляр класса, который мы тестируем.

Пожалуйста, дайте свои предложения.

Использование SpringJUnit4ClassRunner.class вместо MockitoJUnitRunner.class

Ответ 1

Если вы попытаетесь просто выполнить модульное тестирование класса без зависимостей, как вы описываете, в SpringJUnit4ClassRunner нет необходимости. Этот бегун может генерировать полный контекст Spring с (фиктивными) объектами, которые вы можете определить в своей (тестовой) конфигурации контекста приложения. С этим механизмом SpringJUnit4ClassRunner намного медленнее, чем обычный MockitoJUnitRunner.

SpringJUnit4ClassRunner очень мощный для целей интеграционных испытаний.

Я по умолчанию начинаю с MockitoJUnitRunner и, если я достигну пределов этого бегуна, например, потому что мне нужно высмеивать конструкторы, статические методы или частные переменные, я переключаюсь на PowerMockJUnitRunner. Для меня это последнее средство, так как обычно оно говорит, что код плохой и не написан для тестирования. Другие бегуны обычно не нужны для изолированных юнит-тестов.

Ответ 2

Опираясь на ответ Свена, допустим, что вам нужно было протестировать сборку классов при макетировании битов, которые идут в базу данных, или вызвать внешнюю службу, вы бы хотели запустить тест с SpringJUnit4ClassRunner.
Если вы пытались протестировать один Java-класс как единое целое, копируя биты интеграции и локальные соавторы, тогда запуск теста с MockitoJUnitRunner будет достаточным и более быстрым.

Ответ 3

Для модульных тестов нам не нужен Spring, но вам нужно создать экземпляр части Spring для тестов интеграции, издеваясь над уровнем доступа к данным/интеграции. Вы можете использовать TestNG вместо JUnit и использовать любую из этих фреймворков в качестве проводки для интеграции и даже системных интеграционных тестов.