Java单元测试学习(二)

news2024/11/26 10:45:51

Java单元测试学习(二)

使用测试框架JUnit+Mockito和单元测试覆盖率框架JaCoCo

目录结构

在这里插入图片描述

依赖—很好,这里又有个小插曲

打开页面查看覆盖率时一直显示0/0---->最后的解决方式是①添加了maven-surefire-plugin插件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.6</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>mocktio</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>mocktio</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>

        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

        <!-- test -->
        <testcontainers.version>1.15.3</testcontainers.version>
        <mockito.version>4.5.1</mockito.version>
        <junit.version>4.12</junit.version>

        <!-- redis -->
        <commons.version>2.9.0</commons.version>

        <!-- lombok -->
        <lombok.version>1.18.12</lombok.version>

    </properties>

    <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>

        <!-- testcontainers -->
        <dependency>
            <groupId>org.testcontainers</groupId>
            <artifactId>testcontainers</artifactId>
            <version>${testcontainers.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.testcontainers</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>${testcontainers.version}</version>
            <scope>test</scope>
        </dependency>

        <!-- redis -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <!-- spring2.X集成redis所需common-pool2-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>

        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
            <scope>provided</scope>
        </dependency>

        <!--mockito依赖-->
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>${mockito.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-inline</artifactId>
            <version>${mockito.version}</version>
            <scope>test</scope>
        </dependency>

        <!-- jacoco -->
        <dependency>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <version>0.8.7</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <!-- 单测覆盖率-->
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.19.1</version>
            </plugin>

            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>0.8.6</version>
                <executions>
                    <execution>
                        <id>prepare-agent</id>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>report</id>
                        <phase>test</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                    </execution>
                </executions>

            </plugin>
        </plugins>
    </build>

</project>


相关代码

  • UserDao
package com.example.mocktio.dao;

import com.example.mocktio.entity.User;

/**
 * @author Snape
 * @create 2023-06-06 11:02
 * @desc
 */
public interface UserDao {
	/**
	 * 根据name查找user
	 * @param name
	 * @return
	 */
	User getUserByName(String name);

	/**
	 * 保存user
	 * @param user
	 * @return
	 */
	Integer saveUser(User user);

}


  • User
package com.example.mocktio.entity;

import lombok.Data;

/**
 * @author Snape
 * @create 2023-06-06 10:58
 * @desc
 */
@Data
public class User {

	private String name;

	private String sex;

	private Integer age;

	private String address;

}


  • UserServiceImpl
package com.example.mocktio.service.impl;

import com.example.mocktio.dao.UserDao;
import com.example.mocktio.entity.User;
import com.example.mocktio.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author Snape
 * @create 2023-06-06 11:07
 * @desc
 */
@Slf4j
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {

	private final UserDao userDao;

	/**
	 * 根据name查找user
	 * @param name
	 * @return
	 */
	@Override
	public User getUserByName(String name) {
		User userByName = userDao.getUserByName(name);
		if (userByName == null) {
			log.info("查询结果为空");
			throw new RuntimeException("查询结果为空");
		}
		return userByName;
	}

	/**
	 * 保存user
	 * @param user
	 * @return
	 */
	@Override
	public Integer saveUser(User user) {
		if (userDao.getUserByName(user.getName()) != null) {
			throw new RuntimeException("用户存在");
		}
		try {
			return userDao.saveUser(user);
		} catch (Exception e) {
			throw new RuntimeException("保存用户异常");
		}
	}


}


  • UserService
package com.example.mocktio.service;

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

/**
 * @author Snape
 * @create 2023-06-06 11:05
 * @desc
 */
@Service
public interface UserService {
	/**
	 * 根据name查找user
	 * @param name
	 * @return
	 */
	User getUserByName(String name);

	/**
	 * 保存user
	 * @param user
	 * @return
	 */
	Integer saveUser(User user);
}


  • application.properties为空
  • MocktioApplication
package com.example.mocktio;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MocktioApplication {

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

}



  • UserServiceTest
package com.example.mocktio.service.impl;

import com.example.mocktio.MocktioApplicationTests;
import com.example.mocktio.dao.UserDao;
import com.example.mocktio.entity.User;
import lombok.extern.slf4j.Slf4j;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;

import static org.mockito.Mockito.*;

/**
 * @author Snape
 * @create 2023-06-06 11:12
 * @desc
 */
@Slf4j
public class UserServiceTest extends MocktioApplicationTests {

	@InjectMocks
	private UserServiceImpl userService;

	@Mock
	private UserDao userDao;

	/**
	 * 根据name查询user--1
	 */
	@Test
	public void getUserByNameTest1() {

		// mock对象stub操作
		User user = new User();
		user.setName("mockName");
		user.setSex("mockSex");
		user.setAge(18);
		user.setAddress("mockAddress");

		when(userDao.getUserByName("mockName")).thenReturn(user);

		// 执行测试
		User result = userService.getUserByName("mockName");

		// 验证mock对象交互
		verify(userDao).getUserByName(anyString());

		// 验证查询结果
		Assert.assertNotNull("查询结果为空!", result);
		Assert.assertEquals("查询结果错误!", "mockSex", result.getSex());
		Assert.assertEquals("查询结果错误!", Integer.valueOf(18), result.getAge());
		Assert.assertEquals("查询结果错误!", "mockAddress", result.getAddress());

	}

	/**
	 * 根据name查询user--2
	 */
	@Test
	public void getUserByNameTest2() throws Exception {

		when(userDao.getUserByName("mockName")).thenReturn(null);

		// 执行测试
		try {
			userService.getUserByName("mockName");
			throw new Exception("测试失败");
		} catch (RuntimeException e) {
			log.info("查询结果为空-测试通过");
		}

		// 验证mock对象交互
		verify(userDao).getUserByName(anyString());

	}

	/**
	 * 保存user--1
	 */
	@Test
	public void saveUserTest1() throws Exception{

		// mock对象stub操作
		User user = new User();
		user.setName("mockName");
		when(userDao.getUserByName("mockName")).thenReturn(user);

		// 验证用户重复的情况
		try {
			userService.saveUser(user);
			throw new Exception("测试失败");
		} catch (RuntimeException e) {
			log.info("重复用户名保存失败-测试通过");
		}

		// 验证交互
		verify(userDao).getUserByName("mockName");
	}

	/**
	 * 保存user--2
	 */
	@Test
	public void saveUserTest2(){

		// mock对象stub操作
		when(userDao.getUserByName("mockName")).thenReturn(null);
		when(userDao.saveUser(any(User.class))).thenReturn(1);

		// 验证正常保存的情况
		User user = new User();
		user.setName("admin");
		Integer integer = userService.saveUser(user);

		Assert.assertEquals("保存失败!", 1, integer.longValue());

		verify(userDao).saveUser(any(User.class));
		verify(userDao, times(1)).getUserByName(anyString());

	}

}


  • MocktioApplicationTests
package com.example.mocktio;

import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.junit4.SpringRunner;

@SpringBootTest(
		classes = MocktioApplication.class,
		webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@RunWith(SpringRunner.class)
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS)
@ExtendWith(SpringExtension.class)
public abstract class MocktioApplicationTests {

}

  • testng.xml
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" >

<suite name="Test Suite" verbose="1">
    <test name="Test">
        <classes>
            <class name="com.example.mocktio.service.impl.UserServiceTest"/>
            <class name="com.example.mocktio.MocktioApplicationTests"/>
        </classes>
    </test>
</suite>

步骤

  • 执行命令
    在这里插入图片描述
    在这里插入图片描述

  • 点击进入具体的类中可以看到具体覆盖情况
    在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++中流的分类

前言 关于流本质的问题&#xff0c;其实从我刚开始学习C的时候&#xff0c;就已经存在了。当时找了不少的资料&#xff0c;不过一直处于那种知其然而不知其所以然的状态&#xff0c;关于流的本质问题我还是一直没有搞通&#xff0c;始终就是懵懵懂懂的。 不过在今天&#xff0…

智能电能表采集失败的原因和解决方法

智能电能表采集失败的原因和解决方法 智能电能表作为现代电力系统中的重要组成部分&#xff0c;在电能计量、电费结算等方面发挥着关键作用。然而&#xff0c;在实际应用过程中&#xff0c;有时会出现电能表采集失败的情况&#xff0c;这可能源于网络连接故障、数据传输错误等…

数据结构基础-堆

堆实现 计算机科学中&#xff0c;堆是一种基于树的数据结构&#xff0c;通常用完全二叉树实现。堆的特性如下 在大顶堆中&#xff0c;任意节点 C 与它的父节点 P 符合 P.value \geq C.value而小顶堆中&#xff0c;任意节点 C 与它的父节点 P 符合 P.value \leq C.value最顶层…

维护嵌入式 Linux 内核——So Easy

导读Pengutronix 内核黑客 Jan Lbbe 总结了嵌入式 Linux 中正在不断增长的安全威胁&#xff0c;并在这次欧洲嵌入式 Linux 会议上概述了一个计划&#xff0c;以保持长期设备的安全和功能完整。 安全漏洞只发生在 Windows 上的好日子正在快速过去。恶意软件黑客和拒绝服务老手们…

【InsCode AI 创作助手】关于编程人员的未来发展趋势,看看AI们怎么说

一、你平时会使用这类AI工具吗&#xff1f;你对这类型的工具有什么看法&#xff1f; 1&#xff09;会经常使用AI工具吗&#xff1f; 是的&#xff0c;我在生活和工作中经常会使用AI工具&#xff0c;尤其是chatGPT&#xff08;3.5&#xff09;和文心一言&#xff0c;关于midjour…

【微信小程序开发】第 5 节 - 小程序代码的构成

欢迎来到博主 Apeiron 的博客&#xff0c;祝您旅程愉快 &#xff01; 时止则止&#xff0c;时行则行。动静不失其时&#xff0c;其道光明。 目录 1、缘起 2、了解项目的基本组成结构 3、小程序页面的组成部分 4、JSON 配置文件 4.1、json 配置文件的作用 4.2、app.json 文…

http首部(下)

开始头大&#xff0c;哈哈&#xff0c;这个东西真的很无聊且枯燥&#xff0c;奈何最近的学习中经常用到这些知识&#xff0c;还是过一遍比较放心。上一篇博客中我们讨论了http报文首部&#xff0c;其划分为请求头和响应头。请求头主要由请求行、请求字段、通用字段、实体字段组…

ChatGPT请不要和打工人争辩今天星期几

目录 1 今天星期几2 聊聊ChatGPT与工具的结合 1 今天星期几 周五了&#xff0c;一个星期快结束了&#xff0c;闲来问问chatgpt (gpt-3.5) 今天 ( 2023.06.03星期五&#xff09;星期几&#x1f601;&#xff0c;chatgpt给出的回答如下&#xff1a; 今天是2023年6月2号没错&…

Linux系统下安装配置 Nginx 详细教程介绍

Linux系统下安装配置 Nginx 详细教程介绍 一、下载 Nginx 安装包 打开Nginx官网 &#xff1a;nginx: download 然后我们找到一个版本&#xff0c;把鼠标移动到上面&#xff0c;右键 - 复制链接地址 我们使用 wget 命令把Nginx安装包下载到/usr/local/目录中 安装wget yum…

基于html+css的图展示110

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

sid,eld,sidd dataset介绍,dng图像处理

文章目录 SID dataset1. SID dataset 概述2. SID 读取和显示代码3. 一些示例 SIDD datasetELD datasetDNG camera pipeline SID dataset 1. SID dataset 概述 SID 是Learning to See in the Dark 论文中提出的暗光raw数据集 其中包括两个相机的拍摄数据 Sony alpha7S II 和 …

实战演练 | 在 Navicat 16 中创建视图

为了规范化数据库表&#xff0c;常常会将高级别表中的冗余列抽取到单独的子表中。这通常是由于某些字段与父实体具有一对多关系而发生的。例如&#xff0c;请参考以下使用 Navicat Data Modeler 生成的模型&#xff1a; 评估最初是 ups 表的一部分&#xff0c;但这导致了数据冗…

没素材也可以剪辑,根据画面描述搜索影片素材!

随着社交媒体的普及&#xff0c;越来越多的人开始喜欢用短视频分享自己的生活。但是&#xff0c;在剪辑过程中&#xff0c;素材的质量和多样性是很重要的。如果你缺乏素材&#xff0c;可以考虑根据画面描述去搜索一些适合的影片素材。 首先&#xff0c;你需要确定自己需要什么…

自学黑客(网络安全),学习集锦奉上!

想学网络安全&#xff0c;不知道学习方向&#xff1f;我整理了一份渗透测试学习方法&#xff0c;话不多说&#xff0c;上干货。 web安全知识学习&#xff08;理论期&#xff09; 学习web安全基础知识、html语言、python、java、数据库等等。另外端口也可以学习一下3306、3389…

安全中级3:apache中间件漏洞

一、apache换行解析漏洞&#xff08;apache版本在2.4.0~2.4.29&#xff09; 1.原理 该程序是采用黑名单的形式&#xff0c;如果文件后缀名不在名单内即可上传&#xff0c;所以 a.php\x0A不在黑名单列表中&#xff0c;可以上传。但是在fpm-php中x0A是换行符&#xff0c;所以apa…

数据中台浅析(之二)

数据中台浅析 1. 引言 在当今的数字化时代&#xff0c;数据被誉为"新的石油"&#xff0c;越来越多的企业和组织开始深度挖掘数据的价值。在这个过程中&#xff0c;数据中台逐渐成为了数据管理和分析的核心架构&#xff0c;让我们来深入了解一下它。 1.1 数据中台…

数据结构基础-队列

队列 概述 计算机科学中&#xff0c;queue 是以顺序的方式维护的一组数据集合&#xff0c;在一端添加数据&#xff0c;从另一端移除数据。习惯来说&#xff0c;添加的一端称为尾&#xff0c;移除的一端称为头&#xff0c;就如同生活中的排队买商品 In computer science, a qu…

chatgpt赋能python:Python声音分析的应用

Python 声音分析的应用 Python是一种强大的编程语言&#xff0c;具有广泛的应用和使用场景&#xff0c;而其在声音分析领域中的应用也是相当广泛的。本文将会介绍Python在声音分析方面的应用。 什么是声音分析&#xff1f; 声音分析是指通过计算机技术对声音信号进行分析&am…

centos 7 安装部署MySQL主主模式

主机&#xff1a;192.168.1.108&#xff0c;192.168.1.109 192.168.1.108主机上操作 上传mysql安装包&#xff08;略&#xff09; tar zxf mysql.5.7.35.tar.gz –C /data mkdir /var/log/mariadb 使用root用户创建 chown –R unioncloud. /var/log/mariadb 使用root用户执行 切…

SCM Manager XSS漏洞复现(CVE-2023-33829)

一、漏洞描述 漏洞简述 SCM-Manager 是一款开源的版本库管理软件&#xff0c;同时支持 subversion、mercurial、git 的版本库管理。安装简单&#xff0c;功能较强&#xff0c;提供用户、用户组的权限管理 &#xff0c;有丰富的插件支持。由于在MIT的许可下是开源的&#xff0…