Переход с JUnit 4 на выпуск JUnit 5 (от @RunWith до @ExtendWith)
Я пытаюсь преобразовать тестовый код контроллера Spring Boot из JUnit 4 в JUnit 5. Я почти заменил все аннотации JUnit 4 на JUnit 5, но у меня возникли проблемы при попытке заменить @RunWith
с @ExtendWith
,
@ExtendWith(SpringExtension.class)
@WebMvcTest(value = HappyPostController.class, secure = false)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class HappyPostControllerTest {
@Autowired
private MockMvc mockMvc;
@Mock
private HappyPostServiceImpl happyPostService;
@InjectMocks
private HappyPostController happyPostController;
@BeforeAll
public void initialize() {
happyPostController = new HappyPostController(happyPostService);
MockitoAnnotations.initMocks(this);
this.mockMvc = MockMvcBuilders
.standaloneSetup(happyPostController)
.build();
}
@Test
public void testMockCreation() {
Assertions.assertNotNull(happyPostService);
Assertions.assertNotNull(mockMvc);
}
//..... other test methods
}
Ошибки:
java.lang.IllegalStateException: Failed to load ApplicationContext
......
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'happyPostController' defined in file [....\HappyPostController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.rok.capp.service.HappyPostService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
.....
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.rok.capp.service.HappyPostService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
........
Test ignored.
Я пытался найти решение, но не смог. Пожалуйста помоги.
Спасибо
2 ответа
Я не знаю, как выглядела версия этого тестового класса на основе JUnit 4, но приведенный вами пример - ненужная смесь интеграционного теста и модульного теста.
Вы используете SpringExtension
создать ApplicationContext
, но тогда вы никогда не используете ApplicationContext
или любые другие функции из Spring TestContext Framework или Spring Boot Test.
Итак, лучшее решение - это просто избавиться от ненужной поддержки тестирования интеграции и переписать свой тестовый класс следующим образом.
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class HappyPostControllerTest {
@Mock
HappyPostServiceImpl happyPostService;
MockMvc mockMvc;
@BeforeAll
void initialize() {
MockitoAnnotations.initMocks(this);
HappyPostController happyPostController = new HappyPostController(happyPostService);
this.mockMvc = MockMvcBuilders
.standaloneSetup(happyPostController)
.build();
}
@Test
void testMockCreation() {
assertNotNull(happyPostService);
assertNotNull(mockMvc);
}
//..... other test methods
}
С Уважением,
Сэм (автор Spring TestContext Framework)
Я нашел решение здесь: http://www.bytestree.com/spring/spring-boot-2-junit-5-rest-api-unit-testing/
Вот оно обновлено для вашего случая:
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
@ExtendWith(SpringExtension.class)
@WebMvcTest(HappyPostController.class)
class LotteryControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private HappyPostServiceImpl happyPostService;
@Test
public void should_get() throws Exception {
// Given
Mockito.when(happyPostService.whatevermethod()).thenReturn(someresult);
// When
this.mockMvc.perform(MockMvcRequestBuilders.get("/your_api"))
// Then
.andExpect(MockMvcResultMatchers.status().isOk());
}
используя эти зависимости
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.21.0</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>2.21.0</version>
</dependency>