• springboot+junit测试



    参考视频:用Spring Boot编写RESTful API
    参考链接:Spring Boot构建RESTful API与单元测试
    参考链接:Junit自动单元测试以及测试覆盖率简单使用



    一、junit断言

    函数 作用
    TestCase.assertTrue 判断条件是否为真
    TestCase.assertFalse 判断条件是否为假
    TestCase.assertEquals(val1,val2) 判断val1是否和val2相等
    TestCase.assertNotSame(val1,val2) 判断val1是否和val2不相等
    Assert.assertArrayEquals(array1,array2) 判断两个数组相等
    TestCase.fail(message) 测试直接失败,抛出message信息

    注意:
    assertTrue(val1 == val2) 是判断val1和val2是否是同一个实例
    assertEquals(val1, val2) 是判断val1和val2值是否相等

    Assert中有许多方法被淘汰了,这里建议多用TestCase



    二、测试模块

    • 测试模块:我们需要写测试代码的模块
    • 驱动模块:调用我们测试代码的模块
    • 桩模块 :模拟被测试的模块所调用的模块,而不是软件产品的组成的部分,这个桩模块本身不执行任何功能仅在被调用时返回静态值来模拟被调用模块的行为

    桩模块简单实例(税收计算较复杂,可以先模仿一下,作为桩模块,这样就可以不影响被测模块的测试):
    在这里插入图片描述


    三、使用Mockito作为桩模块

    我们在maven中加入Mockito和junit的依赖

            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.mockito</groupId>
                <artifactId>mockito-core</artifactId>
                <scope>test</scope>
            </dependency>
    

    数据库访问层studentDao如下(还未实现方法):

    import org.springframework.stereotype.Repository;
    import whu.xsy.swagger_use.entity.student;
    
    import java.util.List;
    
    @Repository
    public interface studentDao {
    
        //TODO 从数据库获取所有学生信息
        List<student> getAll();
    }
    

    service层如下(调用studentDao):

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import whu.xsy.swagger_use.dao.studentDao;
    import whu.xsy.swagger_use.entity.student;
    
    import java.util.List;
    
    
    @Service
    public class studentService {
    
        @Autowired
        studentDao studentDao;
    
        public List<student> getAll(){
            return studentDao.getAll();
        }
    }
    
    

    接下来开始设置桩模块并开始测试

    此时数据库并没有数据,数据访问层dao也没写好,那么该如何测试service呢?
    我们使用mockito在dao层调用特定方法时模拟返回数据,这样就可以不影响service层的测试,并且即使数据库发生变化(比如环境迁移),也不影响测试。

    简而言之,就是mockito接管了dao层

    import junit.framework.TestCase;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.mockito.Mockito;
    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.SpringJUnit4ClassRunner;
    import whu.xsy.swagger_use.dao.studentDao;
    import whu.xsy.swagger_use.entity.student;
    import whu.xsy.swagger_use.service.studentService;
    
    import java.util.ArrayList;
    import java.util.List;
    
    @SpringBootTest
    @RunWith(SpringJUnit4ClassRunner.class)
    public class SwaggerUseApplicationTests {
    
        @MockBean
        studentDao studentDao;
    
        @Autowired
        studentService studentService;
        
        @Test
        public void contextLoads(){} // 可用来检测springboot环境
    
        //测试studentService
        @Test
        public void testStudentService(){
            //模拟数据库中数据
            List<student> students= new ArrayList<>();
            students.add(new student(1,"xsy"));
            students.add(new student(2,"theory"));
    
            //由于 studentDao 的 getAll() 方法还没写好,所以使用 Mockito 做桩模块,模拟返回数据
            Mockito.when(studentDao.getAll()).thenReturn( students );
    
            //调用studentService.getAll()
            List<student> result = studentService.getAll();
    
            //断言
            TestCase.assertEquals(2,result.size());
            TestCase.assertEquals("xsy",result.get(0).getName());
        }
    }
    
    



    四、使用mockMvc测试web层

    1. 在test类上加上 @AutoConfigureMockMvc注解
    2. 自动注入MockMvc mockMvc;
    3. 对studentController中增删改查接口进行测试
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiImplicitParam;
    import io.swagger.annotations.ApiImplicitParams;
    import io.swagger.annotations.ApiOperation;
    import org.springframework.web.bind.annotation.*;
    import whu.xsy.swagger_use.entity.student;
    
    import java.util.ArrayList;
    import java.util.List;
    
    
    @RestController
    @RequestMapping("/student")
    @Api(value = "/student", tags = "学生模块") //标注在类上的
    public class studentController {
    
        //模拟数据库
        private static List<student> students = new ArrayList<>();
    
        //初始化模拟数据库
        static{
            students.add(new student(1,"xsy"));
            students.add(new student(2,"theory"));
        }
    
        @GetMapping("")
        public List<student> getAll(){
            return students;
        }
    
    
        @PostMapping("")
        public boolean add(student student){
            return students.add(student);
        }
    
    }
    
    

    测试get方法(期望状态200,返回的json中含有xsy,打印返回的信息)

    @SpringBootTest
    @RunWith(SpringJUnit4ClassRunner.class)
    @AutoConfigureMockMvc
    public class SwaggerUseApplicationTests {
    
        @MockBean
        studentDao studentDao;
    
        @Autowired
        studentService studentService;
        
        @Autowired
        MockMvc mockMvc;
        
        @Before
        public void setUp() throws Exception {
            mockMvc = MockMvcBuilders.standaloneSetup(new studentController()).build();
        }
        @Test
        public void testStudentController() throws Exception {
            RequestBuilder request = null;
            //查询所有学生
            request = get("/student/");
            mockMvc.perform(request)
                    .andExpect(status().isOk())
                    .andDo(MockMvcResultHandlers.print())
                    .andExpect(content().string(Matchers.containsString("xsy")));
        }
    
    }
    

    测试通过,并且打印的信息如下:

    MockHttpServletRequest:
          HTTP Method = GET
          Request URI = /student/
           Parameters = {}
              Headers = []
                 Body = <no character encoding set>
        Session Attrs = {}
    
    Handler:
                 Type = whu.xsy.swagger_use.controller.studentController
               Method = whu.xsy.swagger_use.controller.studentController#getAll()
    
    Async:
        Async started = false
         Async result = null
    
    Resolved Exception:
                 Type = null
    
    ModelAndView:
            View name = null
                 View = null
                Model = null
    
    FlashMap:
           Attributes = null
    
    MockHttpServletResponse:
               Status = 200
        Error message = null
              Headers = [Content-Type:"application/json"]
         Content type = application/json
                 Body = [{"id":1,"name":"xsy"},{"id":2,"name":"theory"}]
        Forwarded URL = null
       Redirected URL = null
              Cookies = []
    

    测试post方法:

    本实例中展现了MockMvc如何上传数据和获取返回结果
    测试方法与get类似

            request = post("/student/")
                    .param("id","3")
                    .param("name","ys");
            String result = mockMvc.perform(request)
                    .andExpect(status().isOk())
                    .andReturn().getResponse().getContentAsString();
            TestCase.assertEquals("true",result);
    



    五、批量测试和测试覆盖率

    我们将service的测试和controller的测试分开:
    在这里插入图片描述
    我们需要一次性运行所有的单元测试,则需要配置一次性运行whu.xsy.swagger_use中的所有test类(具体配置见Junit自动单元测试以及测试覆盖率简单使用
    在这里插入图片描述
    在这里插入图片描述
    然后点击run with coverage
    在这里插入图片描述
    就可以运行所有的测试文件,并且可以看到覆盖率
    在这里插入图片描述

  • 相关阅读:
    如何利用InstallShield for Delphi7打包Oracle9i客户端制作C/S数据库应用程序?
    delphi 保存 和 打开 TREE VIEW的节点已经展开的状态
    在Delphi中的TreeView中保存多个数据
    FastReport经验
    农码一生博文索引
    再讲IQueryable<T>,揭开表达式树的神秘面纱
    你知道C#中的Lambda表达式的演化过程吗?
    先说IEnumerable,我们每天用的foreach你真的懂它吗?
    Linq表达式、Lambda表达式你更喜欢哪个?
    你必须知道的EF知识和经验
  • 原文地址:https://www.cnblogs.com/theory/p/11884306.html
Copyright © 2020-2023  润新知