Java单元测试学习(二)

本文介绍了如何使用JUnit和Mockito进行Java单元测试,并通过JaCoCo插件获取测试覆盖率。在项目配置中,添加了maven-surefire-plugin来解决覆盖率显示为0的问题。示例包括了UserDao、Service和测试用例的代码,展示了如何创建和验证mock对象。
摘要由CSDN通过智能技术生成

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>

步骤

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值