zoukankan      html  css  js  c++  java
  • Spring Boot 单元测试示例

    Spring 框架提供了一个专门的测试模块(spring-test),用于应用程序的单元测试。 在 Spring Boot 中,你可以通过spring-boot-starter-test启动器快速开启和使用它。

    在pom.xml文件中引入maven依赖:

    <dependency>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-test</artifactId>

    <scope>test</scope>

    </dependency>

    1. JUnit单元测试

    当你的单元测试代码不需要用到 Spring Boot 功能,而只是一个简单的测试时,你可以直接编写你的 Junit 测试代码:

    public class SimpleJunitTest {

    @Test

    public void testSayHi() {

    System.out.println("Hi Junit.");

    }

    }

    2. Spring Boot单元测试

    当你的集成测试代码需要用到 Spring Boot 功能时,你可以使用@SpringBootTest注解。该注解是普通的 Spring 项目(非 Spring Boot 项目)中编写集成测试代码所使用的@ContextConfiguration注解的替代品。其作用是用于确定如何装载 Spring 应用程序的上下文资源。

    @RunWith(SpringRunner.class)

    @SpringBootTest

    public class BeanInjectTest {

    @Autowired

    private HelloService helloService;

    @Test

    public void testSayHi() {

    System.out.println(helloService.sayHi());

    }

    }

    @Service

    public class HelloService {

    public String sayHi() {

    return "--- Hi ---";

    }

    public String sayHello() {

    return "--- Hello ---";

    }

    }

    当运行 Spring Boot 应用程序测试时,它会自动的从当前测试类所在的包起一层一层向上搜索,直到找到一个@SpringBootApplication或@SpringBootConfiguration注释类为止。以此来确定如何装载 Spring 应用程序的上下文资源。

    主配置启动类的代码为:

    @SpringBootApplication

    public class Application {

    public static void main(String[] args) {

    SpringApplication.run(Application.class);

    }

    }

    如果搜索算法搜索不到你项目的主配置文件,将报出异常:

    java.lang.IllegalStateException: Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=…) with your test

    解决办法是,按 Spring Boot 的约定重新组织你的代码结构,或者手工指定你要装载的主配置文件:

    @RunWith(SpringRunner.class)

    @SpringBootTest(classes = {YourApplication.class})

    public class BeanInjectTest {

    // ...

    }

    基于 Spring 环境的 Junit 集成测试还需要使用@RunWith(SpringJUnit4ClassRunner.class)注解,该注解能够改变 Junit 并让其运行在 Spring 的测试环境,以得到 Spring 测试环境的上下文支持。否则,在 Junit 测试中,Bean 的自动装配等注解将不起作用。但由于 SpringJUnit4ClassRunner 不方便记忆,Spring 4.3 起提供了一个等同于 SpringJUnit4ClassRunner 的类 SpringRunner,因此可以简写成:@RunWith(SpringRunner.class)。

    3. Spring MVC 单元测试

    当你想对 Spring MVC 控制器编写单元测试代码时,可以使用@WebMvcTest注解。它提供了自配置的 MockMvc,可以不需要完整启动 HTTP 服务器就可以快速测试 MVC 控制器。

    import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;

    import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*;

    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

    @RunWith(SpringRunner.class)

    @WebMvcTest(HelloController.class)

    public class HelloControllerTest {

    @Autowired

    private MockMvc mvc;

    @Test

    public void testHello() throws Exception {

    mvc.perform(get("/hello"))

    .andExpect(status().isOk())

    .andDo(print());

    }

    }

    @Controller

    public class HelloController {

    @GetMapping("/hello")

    public String hello(ModelMap model) {

    model.put("message", "Hello Page");

    return "hello";

    }

    }

    使用@WebMvcTest注解时,只有一部分的 Bean 能够被扫描得到,它们分别是:

    @Controller

    @ControllerAdvice

    @JsonComponent

    Filter

    WebMvcConfigurer

    HandlerMethodArgumentResolver

    其他常规的@Component(包括@Service、@Repository等)Bean 则不会被加载到 Spring 测试环境上下文中。

    如果测试的 MVC 控制器中需要@ComponentBean 的参与,你可以使用@MockBean注解来协助完成:

    import static org.mockito.BDDMockito.*;

    import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;

    import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*;

    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

    @RunWith(SpringRunner.class)

    @WebMvcTest(HelloController.class)

    public class HelloControllerTest {

    @Autowired

    private MockMvc mvc;

    @MockBean

    private HelloService helloService;

    @Test

    public void testSayHi() throws Exception {

    // 模拟 HelloService.sayHi() 调用, 返回 "=== Hi ==="

    when(helloService.sayHi()).thenReturn("=== Hi ===");

    mvc.perform(get("/hello/sayHi"))

    .andExpect(status().isOk())

    .andDo(print());

    }

    }

    @Controller

    public class HelloController {

    @Autowired

    private HelloService helloService;

    @GetMapping("/hello/sayHi")

    public String sayHi(ModelMap model) {

    model.put("message", helloService.sayHi());

    return "hello";

    }

    }

    Controller的mock单元测试的另一种方法:

    package net.mingsoft.mdiy.action;
    
    import net.mingsoft.MSApplication;
    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.test.context.junit4.SpringRunner;
    import org.springframework.test.context.web.WebAppConfiguration;
    import org.springframework.test.web.servlet.MockMvc;
    import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
    import org.springframework.test.web.servlet.setup.MockMvcBuilders;
    import org.springframework.web.context.WebApplicationContext;
    
    import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
    
    @WebAppConfiguration
    @RunWith(SpringRunner.class)
    //使用随机端口
    @SpringBootTest(classes = {MSApplication.class})// 指定启动类
    public class ArticleActionMockTest {
    
        @Autowired
        private WebApplicationContext wac;
    
        private MockMvc mvc;
    
        @Before
        public void setUp() {
            mvc = MockMvcBuilders.webAppContextSetup(wac).build();
        }
    
        @Test
        public void testGetMdiyForm() throws Exception{
            this.mvc.perform(get("/ms/mdiy/contentModel/form")).andExpect(status().isOk())
                    .andDo(MockMvcResultHandlers.print());
    
        }
    
    
    
    }

    4. Spring Boot Web 单元测试

    当你想启动一个完整的 HTTP 服务器对 Spring Boot 的 Web 应用编写测试代码时,可以使用@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)注解开启一个随机的可用端口。Spring Boot 针对 REST 调用的测试提供了一个 TestRestTemplate 模板,它可以解析链接服务器的相对地址。

    @RunWith(SpringRunner.class)

    @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)

    public class ApplicationTest {

    @Autowired

    private TestRestTemplate restTemplate;

    @Test

    public void testSayHello() {

    Map result = restTemplate.getForObject("/hello/sayHello", Map.class);

    System.out.println(result.get("message"));

    }

    }

    @Controller

    public class HelloController {

    @Autowired

    private HelloService helloService;

    @GetMapping("/hello/sayHello")

    public @ResponseBody Object helloInfo() {

    Map map = new HashMap<>();

    map.put("message", helloService.sayHello());

    return map;

    }

    }

  • 相关阅读:
    Xamarin.Forms的ActivityIndicator和ProgressBar比较
    SSL剥离工具sslstrip
    服务器SSL/TLS快速检测工具TLLSSLed
    网站robots.txt探测工具Parsero
    采集网站特殊文件Meta信息
    海量端口扫描工具masscan
    Uip + Stm32移植问题总结【转】
    Micro Python 嵌入式以太网社区
    TEA加密算法的C/C++实现
    STM32F4系列外设驱动【不再更新】
  • 原文地址:https://www.cnblogs.com/windpoplar/p/10921823.html
Copyright © 2011-2022 走看看