【Springboot单元测试(速通)】

前言

在实际开发中,如果只是做一个简单的单元测试(不涉及端到端、数据库交互、API调用、消息队列处理等),我为了方便一般都是找块儿地方写一个main方法来跑一下就行了,当然不推荐这样做,怕被领导发现 。所以还是建议在 /src/test/xxx/ 目录下写一个测试类来做测试。

1. 单元测试的测试类

如果只是为了做一个单元测试,比如说测试一个方法是否能正常跑,那么可以按照以下流程创建一个:

maven依赖

这里我所使用的是springboot2.5的版本。他里面自带junit5:测试的框架,所以不需要导入测试类,2.4以下的需要加测试的运行环境@RunWith()

  • import org.junit.jupiter.api.Test;
    测试版本
<?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.5.0</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.lei.demo</groupId>
	<artifactId>demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>spring_boot</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>8</java.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>

		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<version>1.18.12</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

测试类

import org.junit.Test;

public class MyTest {
    @Test
    public void test() {
        long l = System.currentTimeMillis();
        System.out.println(l);
    }
}

要求:

测试类中的方法需要加上@Test;
访问修饰符必须是public,返回类型必须是void;

2. 框架测试的测试类

2.1、所测试的类与springboot的启动类同一个路径下及同层级下

如果需要启动所有上下文进行测试,那么在测试类上面加一个@SpringBootTest就行了,接着就可以使用Bean做测试了,如下:

2.1.1、所测试的类与springboot的启动类在同一层级

在这里插入图片描述

@SpringBootTest
class ApplicationTests {

	@Autowired
	private Dog dog;

	@Autowired
	private Person person;

	@Test
	void contextLoads() {

		System.out.println(dog);

		System.out.println(person);
	}
}

2.1.1、所测试的类与springboot的启动类的下层级(同包名、不同包名都行,规范一般同包名)

在这里插入图片描述

@SpringBootTest
class DogTest {
    @Autowired
    private Dog dog;

    @Autowired
    private Person person;

    @Test
    void contextLoads() {

        System.out.println(dog);

        System.out.println(person);
    }

}

2.2、所测试的类与springboot的启动类不在同一个路径下及同层级下

在这里插入图片描述
如需不在同一包下:需指定包含所需Bean定义的配置类或XML配置文件。这样,SpringRunner在运行测试时,会根据@ContextConfiguration提供的信息来创建一个包含必要Bean的ApplicationContext,从而实现对这些依赖的注入。如果需要同时指定多个类可以这样写:@ContextConfiguration(classes = {ConfigA.class, ConfigB.class, ConfigC.class})。

在这里插入图片描述

@SpringBootTest
@ContextConfiguration(classes = {Dog.class,Person.class})
class DogTest01 {
    @Autowired
    private Dog dog;

    @Autowired
    private Person person;

    @Test
    void contextLoads() {

        System.out.println(dog);

        System.out.println(person);
    }
}

@RunWith:用于指定运行测试类的测试运行器(Test Runner),需要搭配@ContextConfiguration使用。

SpringRunner: Spring提供的一个特殊的测试运行器,它负责解析@SpringBootTest、@ContextConfiguration等Spring相关的注解,并在测试执行前创建和配置Spring应用上下文。

@ContextConfiguration:指定包含所需Bean定义的配置类或XML配置文件。这样,SpringRunner在运行测试时,会根据@ContextConfiguration提供的信息来创建一个包含必要Bean的ApplicationContext,从而实现对这些依赖的注入。如果需要同时指定多个类可以这样写:@ContextConfiguration(classes = {ConfigA.class, ConfigB.class, ConfigC.class})

@SpringBootTest是一个复合注解,其中包含了@RunWith。

注意:

  • @SpringBootTest:启动一个全功能的Spring Boot应用上下文来进行集成测试,可以使用所有的Bean。启动一个测试方法就相当于启动整个项目,比较慢。

  • 如果只是使用几个Bean,那么可以使用 @RunWith(SpringRunner.class) + @ContextConfiguration

2.3、@RunWith注解

@runWith注解作用:

  • @RunWith就是一个运行器
  • @RunWith(JUnit4.class)就是指用JUnit4来运行
  • @RunWith(SpringJUnit4ClassRunner.class),让测试运行于Spring测试环 境,以便在测试开始的时候自动创建Spring的应用上下文
  • @RunWith(Suite.class)的话就是一套测试集合

引申:
Spring Boot 1.5.2 Junit测试
使用 Spring 进行单元测试

方法1:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@EnableAutoConfiguration
public class BBTestAA {
    @Autowired
    private TestRestTemplate testRestTemplate;
 
    //Application.class 为SpringBoot的启动入口类,每个SpringBoot项目大家都会配置
}

如果pom.xml中有如下代码,这行@RunWith(SpringRunner.class)就不会出现SpringRunner,反而有@RunWith(SpringJUnit4ClassRunner.class)

<!--spring-test测试=-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>4.2.4.RELEASE</version>
</dependency>

如果pom.xml中没有这段,则@RunWith(SpringRunner.class)不会报错。如果有这段:①未注释test会报错;②注释test不会报错

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>

如果pom.xml中没有这段,则会报错。如果有这段:①未注释testSpringRunner、SpringBootTest无法引用,会报错;②注释test不会报错

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <version>1.5.9.RELEASE</version>
    <scope>test</scope>
</dependency>

总结起来,想要使用
@RunWith(SpringRunner.class)
@SpringBootTest(classes = App.class)

pom.xml中应该引用这两个

<!--spring-test测试=-->
        <!--<dependency>-->
            <!--<groupId>org.springframework</groupId>-->
            <!--<artifactId>spring-test</artifactId>-->
            <!--<version>4.2.4.RELEASE</version>-->
        <!--</dependency>-->
 
        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>1.5.9.RELEASE</version>
            <!--<scope>test</scope>-->
        </dependency>
 
        <!-- https://mvnrepository.com/artifact/junit/junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <!--<scope>test</scope>-->
        </dependency>

方法2:
如果有test@RunWith报红,没有test会引入该类

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>

如果有test@SpringBootTest报红,没有test会引入该类

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-test</artifactId>
    <version>1.5.9.RELEASE</version>
    <scope>test</scope>
</dependency>

如果是4.2.4.RELEASESpringRunner报红,如果4.2.4.RELEASE会引入该类

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>4.2.4.RELEASE</version>
</dependency>

所以最后要正确使用,需引入这些架包

<!--spring-test测试=-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.3.7.RELEASE</version>
        </dependency>
 
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-test</artifactId>
            <version>1.5.9.RELEASE</version>
        </dependency>
 
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

2.在IDE中新增JunitTest类

@RunWith(SpringRunner.class) //14.版本之前用的是SpringJUnit4ClassRunner.class
@SpringBootTest(classes = Application.class) //1.4版本之前用的是//@SpringApplicationConfiguration(classes = Application.class)
public class SystemInfoServiceImplTest {
 
        @Autowired
        private ISystemInfoService systemInfoservice;
 
        @Test
        public void add() throws Exception {
        }
 
        @Test
         public void findAll() throws Exception {
         }
 
}

主要是注解的更改,如果注解用的不对,会报各种奇怪的问题,例如applicationContext找不到,datasource实例化失败等等。

3.为了支持上面两个注解,maven文件中要用对依赖以及版本,我当时添SpringRunner.class所在的依赖jar时,由于用了idea的auto-imported,IDE自动导入了版本是3.x的,实际应该导入4.x,我一直以为idea导入的是正确的,导致在这上面费时颇多,后来我手工写入就解决了。下面是正确的spring boot test的maven依赖

如果还不懂,请转移到别处:https://blog.youkuaiyun.com/molangmolang/article/details/136575064

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Leoon123

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值