Благодаря ответу @ shazin и некоторым собственным исследованиям я смог решить эту проблему.
По сути, должна быть совместимость между классом бегуна, указанным в @RunWith
, и аннотациями для макетов Mockito.Мы хотим протестировать класс Service
:
Класс обслуживания :
@Component
public class Service {
@Autowired
Environment environment;
public String getProperty() {
return environment.getProperty("prop");
}
}
Если вы используете @RunWith(MockitoJUnitRunner.class)
, вы можете использовать @InjectMocks
и @Mock
аннотации, как показано ниже.Что бы ни было @Autowired
в Service
, оно будет автоматически соединено с макетами:
Тестовый класс с MockitoJUnitRunner
:
@RunWith(MockitoJUnitRunner.class)
public class ServiceTest {
@InjectMocks
Service service;
@Mock
Environment mockEnvironment;
@Before
public void before() {
Mockito.when(mockEnvironment.getProperty("prop")).thenReturn("some-test-value")
}
}
Но вы можете '• Автоматически подключать что-либо в самом тестовом классе .Для этого требуется контекст Spring (контекст Spring необходим для управления bean-компонентами, которые автоматически подключаются к объектам).Вот где @RunWith(SpringRunner.class)
входит в картину.Вы можете использовать его для запуска тестового примера с выделенным контекстом Spring (вы увидите журналы тестовых примеров, показывающие, что новое приложение Spring загружается для каждого тестового класса с аннотацией @RunWith(SpringRunner.class)
).Вам также необходимо предоставить подробности конфигурации с аннотацией @SpringBootTest
.
Предупреждение: тестовый класс с @RunWith(SpringRunner.class)
не будет понимать аннотации @InjectMocks
и @Mock
;вам придется использовать аннотацию @MockBean
.Это эффективно изменит контекст Spring, заменив bean-компоненты их макетами;что-нибудь с аннотацией @Autowired
будет автоматически подключено к фиктивным бобам автоматически:
Тестовый класс с SpringRunner
:
@RunWith(SpringRunner.class)
@SpringBootTest(classes=Application.class)
public class ServiceTest {
@Autowired
Service service;
@MockBean
Environment mockEnvironment;
@Before
public void before() {
Mockito.when(mockEnvironment.getProperty("prop")).thenReturn("some-test-value")
}
}
Итак ...использование @RunWith(SpringRunner.class)
ничего не дало, кроме изменения имен аннотаций (@InjectMocks
-> @Autowired
и @Mock
-> @MockBean
), верно?Неправильно.Использование SpringRunner
дает вам возможность автоматически подключать компоненты в вашем тестовом примере .Так что, если вы хотите использовать фактический Environment
(не фиктивный), вы также можете сделать это;просто автоматически подключите его из специального контекста Spring:
Тестовый класс с SpringRunner
и @Autowired
Environment :
@RunWith(SpringRunner.class)
@SpringBootTest(classes=Application.class)
public class ServiceTest {
@Autowired
Service service;
@Autowired
Environment environment;
@Test
public void testServiceGetProperty() {
assertEquals(environment.getProperty("prop"), service.getProperty("prop");
}
}
И это решает проблему.