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

    开发环境:IntelliJ IDEA 2019.2.2
    Spring Boot版本:2.1.8

    IDEA新建一个Spring Boot项目后,pom.xml默认包含了Web应用和单元测试两个依赖包。
    如下:

        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>

    一、测试Web服务

    1、新建控制器类 HelloController.java

    package com.example.demo.controller;
    
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class HelloController {
        @RequestMapping("/")
        public String index() {
            return "index";
        }
    
        @RequestMapping("/hello")
        public String hello() {
            return "hello";
        }
    }

    2、新建测试类 HelloControllerTest.cs

    下面WebEnvironment.RANDOM_PORT会启动一个真实的Web容器,RANDOM_PORT表示随机端口,如果想使用固定端口,可配置为
    WebEnvironment.DEFINED_PORT,该属性会读取项目配置文件(如application.properties)中的端口(server.port)。
    如果没有配置,默认使用8080端口。

    package com.example.demo.controller;
    
    import org.junit.Assert;
    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.boot.test.web.client.TestRestTemplate;
    import org.springframework.test.context.junit4.SpringRunner;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
    public class HelloControllerTest {
    
        @Autowired
        private TestRestTemplate restTemplate;
    
        @Test
        public void testIndex(){
            String result = restTemplate.getForObject("/",String.class);
            Assert.assertEquals("index", result);
        }
    
        @Test
        public void testHello(){
            String result = restTemplate.getForObject("/",String.class);
            Assert.assertEquals("Hello world", result);//这里故意写错
        }
    }

    在HelloControllerTest.java代码中右键空白行可选择Run 'HelloControllerTest',测试类里面所有方法。
    (如果只想测试一个方法如testIndex(),可在testIndex()代码上右键选择Run 'testIndex()')
    运行结果如下,一个通过,一个失败。

    二、模拟Web测试

    新建测试类 HelloControllerMockTest.java
    设置WebEnvironment属性为WebEnvironment.MOCK,启动一个模拟的Web容器。
    测试方法中使用Spring的MockMvc进行模拟测试。

    package com.example.demo.controller;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    import org.springframework.test.web.servlet.MockMvc;
    import org.springframework.test.web.servlet.MvcResult;
    import org.springframework.test.web.servlet.ResultActions;
    import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
    
    import java.net.URI;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)//MOCK为默认值,也可不设置
    @AutoConfigureMockMvc
    public class HelloControllerMockTest {
        @Autowired
        private MockMvc mvc;
    
        @Test
        public  void testIndex() throws Exception{
            ResultActions ra = mvc.perform(MockMvcRequestBuilders.get(new URI("/")));
            MvcResult result = ra.andReturn();
            System.out.println(result.getResponse().getContentAsString());
        }
    
        @Test
        public  void testHello() throws Exception{
            ResultActions ra = mvc.perform(MockMvcRequestBuilders.get(new URI("/hello")));
            MvcResult result = ra.andReturn();
            System.out.println(result.getResponse().getContentAsString());
        }
    }

    右键Run 'HelloControllerMockTest',运行结果如下:

    三、测试业务组件

    1、新建服务类 HelloService.java

    package com.example.demo.service;
    
    import org.springframework.stereotype.Service;
    
    @Service
    public class HelloService {
        public String hello(){
            return "hello";
        }
    }

    2、新建测试类 HelloServiceTest.java

    WebEnvironment属性设置为NONE,不会启动Web容器,只启动Spring容器。

    package com.example.demo.service;
    
    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;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
    public class HelloServiceTest {
        @Autowired
        private HelloService helloService;
    
        @Test
        public void testHello(){
            String result = helloService.hello();
            System.out.println(result);
        }
    }

    右键Run 'HelloServiceTest',运行结果如下:

    四、模拟业务组件

    假设上面的HelloService.cs是操作数据库或调用第三方接口,为了不让这些外部不稳定因素影响单元测试的运行结果,可使用mock来模拟
    某些组件的返回结果。
    1、新建一个服务类 MainService.java

    里面的main方法会调用HelloService的方法

    package com.example.demo.service;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    @Service
    public class MainService {
        @Autowired
        private HelloService helloService;
    
        public void main(){
            System.out.println("调用业务方法");
            String result = helloService.hello();
            System.out.println("返回结果:" + result);
        }
    }

    2、新建测试类 MainServiceMockTest.java

    下面代码中,使用MockBean修饰需要模拟的组件helloService,测试方法中使用Mockito的API模拟helloService的hello方法返回。

    package com.example.demo.service;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.mockito.BDDMockito;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.boot.test.mock.mockito.MockBean;
    import org.springframework.test.context.junit4.SpringRunner;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class MainServiceMockTest {
        @MockBean
        private HelloService helloService;
        @Autowired
        private MainService mainService;
    
        @Test
        public void testMain(){
            BDDMockito.given(this.helloService.hello()).willReturn("hello world");
            mainService.main();
        }
    }

    右键Run 'MainServiceMockTest',运行结果如下:

    五、IDEA项目结构图

  • 相关阅读:
    【转】Java操作CSV文件导入导出
    【转】Java压缩和解压文件工具类ZipUtil
    Python之multiprocessing.Pool(创建多个子进程)
    Openstack平台虚拟机疏散失败提示(pymysql.err.OperationalError) (2013, 'Lost connection to MySQL server during query')问题
    kubernetes部署redis主从高可用集群
    Ceph性能测试
    python日志模块
    kubernetes删除pod,pod一直处于Terminating状态
    python执行提示“ImportError: No module named OpenSSL.crypto”
    二进制部署kubernetes集群_kube-apiserver提示"watch chan error: etcdserver: mvcc: required revision has been compacted'
  • 原文地址:https://www.cnblogs.com/gdjlc/p/11553274.html
Copyright © 2011-2022 走看看