从JUnit 4迁移到JUnit 5问题(@RunWith到@ExtendWith)

时间:2018-05-17 05:13:29

标签: unit-testing spring-boot junit5

我正在尝试将Spring引导控制器的测试代码从JUnit 4转换为JUnit 5.我几乎用JUnit 5替换了JUnit 4的所有注释,但在尝试用{1}替换@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 个答案:

答案 0 :(得分:1)

我不知道你的基于JUnit 4的测试类版本是什么样的,但你提供的示例是集成测试和单元测试的不必要的混合。

您正在使用SpringExtension创建ApplicationContext,但之后您永远不会使用{em> Spring TestContext Framework 中的ApplicationContext或任何其他功能或 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
}

此致

Sam (Spring TestContext Framework的作者)

答案 1 :(得分:0)

我在这里找到了解决方案: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>