Java 如何为 Spring Boot Controller 端点编写单元测试

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29053974/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 07:16:35  来源:igfitidea点击:

How to write a unit test for a Spring Boot Controller endpoint

javaunit-testingjunitspring-bootspring-test-mvc

提问by user6123723

I have a sample Spring Boot app with the following

我有一个示例 Spring Boot 应用程序,其中包含以下内容

Boot main class

引导主类

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

Controller

控制器

@RestController
@EnableAutoConfiguration
public class HelloWorld {
    @RequestMapping("/")
    String gethelloWorld() {
        return "Hello World!";
    }

}

What's the easiest way to write a unit test for the controller? I tried the following but it complains about failing to autowire WebApplicationContext

为控制器编写单元测试的最简单方法是什么?我尝试了以下操作,但它抱怨无法自动装配 WebApplicationContext

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = DemoApplication.class)
public class DemoApplicationTests {

    final String BASE_URL = "http://localhost:8080/";

    @Autowired
    private WebApplicationContext wac;

    private MockMvc mockMvc;

    @Before
    public void setup() {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
    }

    @Test
    public void testSayHelloWorld() throws Exception{

         this.mockMvc.perform(get("/")
                 .accept(MediaType.parseMediaType("application/json;charset=UTF-8")))
                 .andExpect(status().isOk())
                 .andExpect(content().contentType("application/json"));
    }

    @Test
    public void contextLoads() {
    }

}

采纳答案by Master Slave

Spring MVC offers a standaloneSetupthat supports testing relatively simple controllers, without the need of context.

Spring MVC 提供了一个独立的Setup,它支持测试相对简单的控制器,而不需要上下文。

Build a MockMvc by registering one or more @Controller's instances and configuring Spring MVC infrastructure programmatically. This allows full control over the instantiation and initialization of controllers, and their dependencies, similar to plain unit tests while also making it possible to test one controller at a time.

通过注册一个或多个@Controller 的实例并以编程方式配置 Spring MVC 基础设施来构建 MockMvc。这允许完全控制控制器的实例化和初始化及其依赖项,类似于普通的单元测试,同时还可以一次测试一个控制器。

An example test for your controller can be something as simple as

控制器的示例测试可以很简单

public class DemoApplicationTests {

    private MockMvc mockMvc;

    @Before
    public void setup() {
        this.mockMvc = standaloneSetup(new HelloWorld()).build();
    }

    @Test
    public void testSayHelloWorld() throws Exception {
        this.mockMvc.perform(get("/")
           .accept(MediaType.parseMediaType("application/json;charset=UTF-8")))
           .andExpect(status().isOk())
           .andExpect(content().contentType("application/json"));

    }
}

回答by Charles Wang

Adding @WebAppConfiguration(org.springframework.test.context.web.WebAppConfiguration) annotation to your DemoApplicationTests class will work.

@WebAppConfiguration( org.springframework.test.context.web.WebAppConfiguration) 注释添加到 DemoApplicationTests 类将起作用。

回答by geoand

The new testing improvements that debuted in Spring Boot 1.4.M2can help reduce the amount of code you need to write situation such as these.

Spring Boot 中首次推出的新测试改进1.4.M2可以帮助减少编写此类情况所需的代码量。

The test would look like so:

测试看起来像这样:

import static org.springframework.test.web.servlet.request.MockMvcRequestB??uilders.get; 
import static org.springframework.test.web.servlet.result.MockMvcResultMat??chers.content; 
import static org.springframework.test.web.servlet.result.MockMvcResultMat??chers.status;

    @RunWith(SpringRunner.class)
    @WebMvcTest(HelloWorld.class)
    public class UserVehicleControllerTests {

        @Autowired
        private MockMvc mockMvc;

        @Test
        public void testSayHelloWorld() throws Exception {
            this.mockMvc.perform(get("/").accept(MediaType.parseMediaType("application/json;charset=UTF-8")))
                    .andExpect(status().isOk())
                    .andExpect(content().contentType("application/json"));

        }

    }

See thisblog post for more details as well as the documentation

有关更多详细信息以及文档,请参阅博客文章

回答by Siva Kumar

Here is another answer using Spring MVC's standaloneSetup. Using this way you can either autowire the controller class or Mock it.

这是使用 Spring MVC 的 standaloneSetup 的另一个答案。使用这种方式,您可以自动装配控制器类或模拟它。

    import static org.mockito.Mockito.mock;
    import static org.springframework.test.web.server.request.MockMvcRequestBuilders.get;
    import static org.springframework.test.web.server.result.MockMvcResultMatchers.content;
    import static org.springframework.test.web.server.result.MockMvcResultMatchers.status;

    import org.junit.Before;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.http.MediaType;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    import org.springframework.test.web.server.MockMvc;
    import org.springframework.test.web.server.setup.MockMvcBuilders;


    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
    public class DemoApplicationTests {

        final String BASE_URL = "http://localhost:8080/";

        @Autowired
        private HelloWorld controllerToTest;

        private MockMvc mockMvc;

        @Before
        public void setup() {
            this.mockMvc = MockMvcBuilders.standaloneSetup(controllerToTest).build();
        }

        @Test
        public void testSayHelloWorld() throws Exception{
            //Mocking Controller
            controllerToTest = mock(HelloWorld.class);

             this.mockMvc.perform(get("/")
                     .accept(MediaType.parseMediaType("application/json;charset=UTF-8")))
                     .andExpect(status().isOk())
                     .andExpect(content().mimeType(MediaType.APPLICATION_JSON));
        }

        @Test
        public void contextLoads() {
        }

    }