【单元测试】Controller、Service、Repository 层的单元测试

Controller、Service、Repository 层的单元测试

  • 1.Controller 层的单元测试
    • 1.1 创建一个用于测试的控制器
    • 1.2 编写测试
  • 2.Service 层的单元测试
    • 2.1 创建一个实体类
    • 2.2 创建服务类
    • 2.3 编写测试
  • 3.Repository

1.Controller 层的单元测试

下面通过实例演示如何在控制器中使用 MockMvc 进行单元测试。

1.1 创建一个用于测试的控制器

package com.example.demo.controller;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    @RequestMapping("/hello")
    public String hello(String name) {
        return "hello " + name;
    }
}
  • @RestController:代表这个类是 REST 风格的控制器,返回 JSON/XML 类型的数据。
  • @RequestMapping:用于配置 URL 和方法之间的映射,可用在类和方法上。用于方法上,则其路径会继承用在类的路径上。

1.2 编写测试

package com.example.demo.controller;

import org.junit.Assert;
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.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
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.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import static org.junit.Assert.*;

@SpringBootTest
@RunWith(SpringRunner.class)
public class HelloControllerTest {
    //启用web上下文
    @Autowired
    private WebApplicationContext webApplicationContext;
    private MockMvc mockMvc;

    @Before
    public void setUp() throws Exception{
        //使用上下文构建mockMvc
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
    }
    @Test
    public void hello() throws Exception {
        // 得到MvcResult自定义验证
        // 执行请求
        MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.get("/hello")
                .contentType(MediaType.APPLICATION_JSON_UTF8)
                //传入参数
                .param("name","longzhonghua")
                //接收的类型
                .accept(MediaType.APPLICATION_JSON_UTF8))
                //等同于Assert.assertEquals(200,status);
                //判断接收到的状态是否是200
                .andExpect(MockMvcResultMatchers.status().isOk())
                 //等同于 Assert.assertEquals("hello longzhonghua",content);
                .andExpect(MockMvcResultMatchers.content().string("hello longzhonghua"))
                .andDo(MockMvcResultHandlers.print())
        //返回MvcResult
        .andReturn();
        //得到返回代码
        int status = mvcResult.getResponse().getStatus();
        //得到返回结果
        String content = mvcResult.getResponse().getContentAsString();
        //断言,判断返回代码是否正确
        Assert.assertEquals(200,status);
        //断言,判断返回的值是否正确
        Assert.assertEquals("hello longzhonghua",content);
    }
}
  • @SpringBootTest:是 Spring Boot 用于测试的注解,可指定入口类或测试环境等。
  • @RunWith(SpringRunner.class):让测试运行于 Spring 的测试环境。
  • @Test:表示一个测试单元。
  • WebApplicationContext:启用 Web 上下文,用于获取 Bean 中的内容。
  • @Before:表示在测试单元执行前执行。这里使用上下文构建 MockMvc。
  • MockMvcRequestBuilders.get:指定请求方式是 GET。一般用浏览器打开网页就是 GET 方式。

运行测试,在控制器中会输出以下结果:

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /hello
       Parameters = {name=[longzhonghua]}
          Headers = [Content-Type:"application/json;charset=UTF-8", Accept:"application/json;charset=UTF-8"]
             Body = null
    Session Attrs = {}

Handler:
             Type = com.example.demo.controller.HelloController
           Method = public java.lang.String com.example.demo.controller.HelloController.hello(java.lang.String)

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;charset=UTF-8", Content-Length:"18"]
     Content type = application/json;charset=UTF-8
             Body = hello longzhonghua
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

在上述结果中可以看到 访问方式路径参数访问头ModelAndViewFlashMapMockHttpServletResponse

2.Service 层的单元测试

本实例演示如何在 Service 中使用 Assert 进行单元测试。

2.1 创建一个实体类

package com.example.demo.entity;

import lombok.Data;
import lombok.Getter;
import lombok.Setter;

@Data
public class User {
    private String name;
    private int age;
}

2.2 创建服务类

这里用 @Service 来标注服务类,并实例化一个 User 对象。

package com.example.demo.service;

import com.example.demo.entity.User;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    public User getUserInfo(){
        User user = new User();
        user.setName("pipi");
        user.setAge(18);
        return user;
    }
}

2.3 编写测试

编写测试用于比较实例化的实体 User 和测试预期值是否一样。

package com.example.demo.service;

import com.example.demo.entity.User;
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.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;

import static org.hamcrest.CoreMatchers.*;

//表明要在测试环境运行,底层使用的junit测试工具
@RunWith(SpringRunner.class)
// SpringJUnit支持,由此引入Spring-Test框架支持!

//启动整个spring的工程
@SpringBootTest
public class UserServiceTest {
    @Autowired
    private UserService userService;

    @Test
    public void getUserInfo() {
        User user = userService.getUserInfo();
        //比较实际的值和用户预期的值是否一样
        Assert.assertEquals(18, user.getAge());
        Assert.assertThat(user.getName(), is("pipixia"));

    }
}

运行测试,结果显示出错,表示期望的值和实际的值不一样。

在这里插入图片描述

3.Repository

Repository 层主要用于对数据进行增加、删除、修改和查询操作、它相当于仓库管理员的进出货操作。

下面通过实例演示如何在 Repository 中进行单元测试,以及使用 @Transactional 注解进行回滚操作。

package com.example.demo.repository;

import com.example.demo.entity.Card;
import org.junit.After;
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.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.List;

import static org.junit.Assert.*;

@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
public class CardRepositoryTest {
    @Autowired
    private CardRepository cardRepository;

    @Test
    public void testQuery() {
        // 查询操作
        List<Card> list = cardRepository.findAll();
        for (Card card : list) {
            System.out.println(card);
        }
    }

    @Test
    public void testRollBack() {
        // 查询操作
        Card card = new Card();
        card.setNum(3);
        cardRepository.save(card);
        //throw new RuntimeException();
    }
}
  • @Transactional:即回滚的意思。所有方法执行完之后哦,回滚成原来的样子。
  • testRollBack 方法:执行添加一条记录。如果开启了 @Transactional,则会在添加之后进行回滚,删除刚添加的数据,如果注释掉 @Transactional,则完成添加后不回滚。大家在测试时可以尝试去掉或添加 @Transactional 状态下的不同效果。这里的 @Transactional 放在类上,也可以加在方法上作用于方法。

运行 testQuery 测试,控制台输出如下:

在这里插入图片描述
在这里插入图片描述

运行 testRollBack 测试,并添加 @Transactional,控制台输出如下:

在这里插入图片描述

上述结果表示先添加,然后操作被立即回滚了。

在这里插入图片描述

运行 testRollBack 测试,去掉 @Transactional,控制台输出如下:

在这里插入图片描述
在这里插入图片描述

注:设置了 id 为自增键。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/756638.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【漏洞复现】飞企互联——SQL注入

声明&#xff1a;本文档或演示材料仅供教育和教学目的使用&#xff0c;任何个人或组织使用本文档中的信息进行非法活动&#xff0c;均与本文档的作者或发布者无关。 文章目录 漏洞描述漏洞复现测试工具 漏洞描述 飞企互联-FE企业运营管理平台是一个基于云计算、智能化、大数据…

JAVA高级进阶13单元测试、反射、注解

第十三天、单元测试、反射、注解 单元测试 介绍 单元测试 就是针对最小的功能单元(方法)&#xff0c;编写测试代码对其进行正确性测试 咱们之前是如何进行单元测试的&#xff1f; 有啥问题 &#xff1f; 只能在main方法编写测试代码&#xff0c;去调用其他方法进行测试。 …

Django 自定义过滤器

1&#xff0c;编写自定义过滤器并注册 创建目录 Test/app5/templatetags 分别创建文件 Test/app5/templatetags/__init__.py Test/app5/templatetags/myfilter.py 添加过滤器脚本 Test/app5/templatetags/myfilter.py from django import template register template.…

shell:处理命令行参数 获取用户输入

1. 命令行参数 1.1 位置参数 bash shell会将一些称为位置参数(positional parameter)的特殊变量分配给输入到命令行中的 所有参数。这也包括shell所执行的脚本名称。位置参数变量是标准的数字:$0是程序名&#xff0c;$1是第 一个参数&#xff0c;$2是第二个参数&#xff0c;依…

基于C语言的Jacobi迭代和Gauss-Seidel迭代的方程组求解实现

文章目录 Jacobi迭代方法介绍Gauss-Seidel迭代方法介绍具体代码实现示例题目实现效果 Jacobi迭代方法介绍 Jacobi迭代法是一种简单的迭代求解方法&#xff0c;适用于严格对角占优矩阵。其基本思想是利用当前迭代步的已知解来更新下一个迭代步的解。在C语言实现中&#xff0c;我…

网格处理库 pmp-library 编译及应用笔记 -- 已全部解决√

多边形网格处理库Polygon Mesh Processing Library&#xff0c;简称pmp-library的 编译及应用笔记 – 已全部解决√ 官网&#xff1a;https://www.pmp-library.org/index.html 代码&#xff1a;https://github.com/pmp-library/pmp-library 平台&#xff1a;Ubuntu1 20.04&…

Python功能制作之使用streamlit做一个简单的WebUI

使用Streamlit创建WebUI 1. 什么是Streamlit Streamlit 是一个开源的Python库&#xff0c;用于快速创建美观的Web应用。 它适合数据科学家和机器学习工程师&#xff0c;因为它能够以最小的代码量将数据应用程序带到浏览器中。通过简单的Python脚本&#xff0c;可以创建交互式…

C++中的三大池:线程池,内存池,数据库连接池

C中有三大池&#xff0c;即我们常说的&#xff1a;线程池&#xff0c;内存池&#xff0c;数据库连接池。 一.线程池 多线程同时访问共享资源造成数据混乱的原因就是因为CPU的上下文切换导致&#xff0c;线程池就是为了解决此问题而生。 多线程常用的有&#xff1a;std::threa…

基于Spring Boot的校园失物招领系统

1 项目介绍 1.1 研究的背景及意义 在网络时代飞速发展的今天&#xff0c;随着网络技术日臻完善&#xff0c;我们的生活方式正经历深刻变革。在物质追求日益增长的同时&#xff0c;提升个人精神境界也成为了现代人的共同向往&#xff0c;而阅读则是滋养心灵、丰富精神世界的重…

【SpringBoot3学习 | 第1篇】SpringBoot3介绍与配置文件

文章目录 前言 一. SpringBoot3介绍1.1 SpringBoot项目创建1. 创建Maven工程2. 添加依赖(springboot父工程依赖 , web启动器依赖)3. 编写启动引导类(springboot项目运行的入口)4. 编写处理器Controller5. 启动项目 1.2 项目理解1. 依赖不需要写版本原因2. 启动器(Starter)3. Sp…

C++——探索智能指针的设计原理

前言: RAII是资源获得即初始化&#xff0c; 是一种利用对象生命周期来控制程序资源地手段。 智能指针是在对象构造时获取资源&#xff0c; 并且在对象的声明周期内控制资源&#xff0c; 最后在对象析构的时候释放资源。注意&#xff0c; 本篇文章参考——C 智能指针 - 全部用法…

Arduino - TM1637 4 位 7 段显示器

Arduino - TM1637 4 位 7 段显示器 Arduino-TM1637 4 位 7 段显示器 A standard 4-digit 7-segment display is needed for clock, timer and counter projects, but it usually requires 12 connections. The TM1637 module makes it easier by only requiring 4 connectio…

电通出席2024年世界经济论坛(WEF),重申推动可持续发展创新和人才培育的承诺

中国&#xff0c;上海——电通将出席世界经济论坛2024年新领军者年会&#xff08;夏季达沃斯&#xff09;&#xff0c;本次大会将于6月25日至6月27日在中国大连举行。 2024年世界经济论坛主题为“未来增长的新前沿”&#xff0c;将聚焦于全球经济复苏、通胀缓解&#xff0c;以…

计算机毕业设计Python+Spark知识图谱微博预警系统 微博推荐系统 微博可视化 微博数据分析 微博大数据 微博爬虫 微博预测系统 大数据毕业设计

课题名称 基于Bert模型对微博的言论情感分析设计与实现 课题来源 课题类型 BY 指导教师 学生姓名 专 业 计算机科学与技术 学 号 开题报告内容&#xff1a;&#xff08;调研资料的准备&#xff0c;设计/论文的目的、要求、思路与预期成果&#xff1b;…

汽车免拆诊断案例 | 2016 款吉利帝豪EV车无法加速

故障现象 一辆2016款吉利帝豪EV车&#xff0c;累计行驶里程约为28.4万km&#xff0c;车主反映车辆无法加速。 故障诊断 接车后路试&#xff0c;行驶约1 km&#xff0c;踩下加速踏板&#xff0c;无法加速&#xff0c;车速为20 km/h左右&#xff0c;同时组合仪表上的电机及控制…

CST--如何在PCB三维模型中自由创建离散端口

在使用CST电磁仿真软件进行PCB的三维建模时&#xff0c;经常会遇到不能自动创建离散端口的问题&#xff0c;原因有很多&#xff0c;比如&#xff1a;缺少元器件封装、开路端口、多端子模型等等&#xff0c;这个时候&#xff0c;很多人会选择手动进行端口创建&#xff0c;但是&a…

centos 7.2 离线部署 mysql 5.7.37

1.安装依赖 清楚mysql从图的依赖 rpm -qa|grep mariadb 存在冲突依赖,进行卸载 rpm -e --nodeps mariadb-libs-5.5.44-2.el7.centos.x86_64 确认gcc版本 ldd --version 安装mysql5.7所需要的依赖 mkdir -p /root/AllInstalls 只下载不安装,用于放到其他机器: yum inst…

Java对象创建过程

在日常开发中&#xff0c;我们常常需要创建对象&#xff0c;那么通过new关键字创建对象的执行中涉及到哪些流程呢&#xff1f;本文主要围绕这个问题来展开。 类的加载 创建对象时我们常常使用new关键字。如下 ObjectA o new ObjectA();对虚拟机来讲首先需要判断ObjectA类的…

一款轻量级的通信协议---MQTT (内含Linux环境搭建)

目录 MQTT MQTT的关键特点&#xff1a; 应用场景 Linux环境搭建&#xff1a; 1. 安装mosquitto 2. Linux下客户端进行通信 3. PC端和Linux下进行通信 安装MQTT. fx 4. MQTT.fx的使用 1. 点击连接 ​编辑 2. 连接成功 3. 订阅主题或者给别的主题发送消息 遇到的问…

Qt 5.14.2+Android环境搭建

1. 安装QT5.14.2的过程中&#xff0c;选中套件&#xff08;kit&#xff09; qt for android。 如果已经安装了qt creator但没有安装该套件&#xff0c;可以找到在qt安装目录下的MaintenanceTool.exe&#xff0c;运行该程序添加套件。 2. 安装jdk8&#xff0c;android sdk&…