JUnit 单元测试


 

说明

  • 一般来说,封装的工具类库、服务端接口的核心service,都应该提供相应的单元测试;
  • junit 中有2个 @Test 注解:junit4 中开始提供 @org.junit.Test ,junit5 中开始提供 @org.junit.jupiter.api.Test,这2个注解在普通java项目中的使用基本相同,需要注意的是低版本 springboot 中可能没有 @org.junit.jupiter.api.Test,只能使用 @org.junit.Test 。

 

junit的使用

  • 包、类的路径与源码保持一致,测试类通常命名为原类名+Test,测试方法名一般命名为test+原方法名
  • 测试方法不能有入参、返回值类型要是void
public class XxxTest {

    @Before //执行每个测试方法之前都会先执行@Before标注的方法
    public void init(){

    }

    @After //执行每个测试方法之后都会执行@After标注的方法
    public void destroy(){

    }
    
    @Test
    public void testA(){
        //提示信息可以缺省
        Assert.assertEquals("提示信息", "期望数据", "实际数据");
    }

    @Test
    public void testB(){

    }

}

 

spring整合junit

依赖
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.2.8.RELEASE</version>
    <scope>test</scope>
</dependency>

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

 

编写单元测试
@RunWith(SpringRunner.class)  //提供spring容器环境,这样@Autowired之类的注解才能注入所需依赖。如果当前测试类不需要spring容器环境,可缺省
@ContextConfiguration(locations = "classpath:spring-config.xml")  //指定配置文件的位置
// @ContextConfiguration(locations = {"classpath:spring-config1.xml","classpath:spring-config2.xml"})  //有多个时写成数组
public class UserMapperTest {

    @Autowired  //注入要测试的类的实例
    private UserMapper userMapper;

    @BeforeClass  //在测试这个类之前执行,常用于初始化静态成员变量
    public static void BeforeClass(){

    }

    @AfterClass  //在测试这个类之后执行
    public static void AfterClass(){

    }

    @Before  //每个测试方法执行之前都会执行此方法,常用于初始化实例的成员变量
    public void before(){

    }

    @After  //每个测试方法执行完毕后都会执行此方法
    public void after(){

    }

    @Test  //测试方法
    public void findUserByIdTest(){
        User user = userMapper.findUserById(1);
        //使用的Assert是junit中的,不要导错了
        Assert.assertEquals("返回的User对象与预期不符,未通过测试", user, new User(1,"chy",20));
    }

    @Ignore  //测试这个类时会忽略|跳过此方法,可备注一些信息
    // @Ignore("对应方法还存在bug,暂不测试")
    public void updateUserTest(){
        //.....
    }

}

注意

  • @RunWith(SpringRunner.class),SpringRunner 是 SpringJUnit4ClassRunner 的别名,2个都可以
  • 在测试类前后执行用的是 @BeforeClass、@AfterClass,不是 @BeforeTestClass、@AfterTestClass
  • @BeforeClass、@AfterClass 标注的方法必须是没有入参、返回值是void的静态方法

 

测试

选择JUnit
在这里插入图片描述

 

springboot整合junit

依赖

用Spring Initializr创建springboot项目时,默认会自动添加junit的依赖。如果不使用Spring Initializr,可以手动添加依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>org.junit.vintage</groupId>
            <artifactId>junit-vintage-engine</artifactId>
        </exclusion>
    </exclusions>
</dependency>

junit-vintage-engine是使用老版本junit所需的依赖,不需要,使用<exclusions>排除,当然留着也行。

 

编写单元测试
@RunWith(SpringRunner.class)
@SpringBootTest  // @SpringBootTest(classes = {MallApplication.class} )  //指定源码中的引导类,如果源码中只有1个引导类,可缺省classes属性。
// @WebAppConfiguration   //模拟ServletContext、提供web环境,如果这个测试类不涉及web,可缺省
public class UserMapperTest {

    @Autowired
    private UserMapper userMapper;

    @BeforeClass
    public static void BeforeClass(){

    }

    @AfterClass
    public static void AfterClass(){

    }

    @Before
    public void before(){

    }

    @After
    public void after(){

    }

    @Test
    public void testFindUserById(){
        User user = userMapper.findUserById(1);
        Assert.assertEquals("返回的User对象与预期不符,未通过测试", user, new User(1,"chy",20));
    }

    @Ignore
    public void testUpdateUser(){
        //.....
    }

}

在高版本springboot(springboot 2.2 版本)中, spring-boot-starter-test 已经移除了junit 的部分依赖

  • 不需要写、也不再提供 @RunWith 注解;
  • 不再提供 Assert 类,可以使用 Assertions 或spring的 Assert 代替。

 

常用技巧

1、每个测试类上都要写@RunWith、@SpringBootTest,很麻烦,可以封装为一个类,测试类都继承该类

@RunWith(SpringRunner.class)
@SpringBootTest
public class BaseTest {

}

 

2、打包测试
一个测试类一个测试类地去点击运行,很麻烦,可以把测试类打包到一个类中,运行该类即可

@RunWith(Suite.class)
@Suite.SuiteClasses({UserMapperTest.class, GooodsMapperTest.class})  //数组中写要运行的测试类
public class TestSuits {

}

 

3、私有方法的常见测试方式

  • 直接在目标类中写测试,比如直接写个main方法
  • 将目标代码拷贝到单元测试中
  • 将方法改为public,测试完再改回去
  • 将方法改为public,在方法上标注guava的 @VisibleForTesting 或 jetbrains的 @TestOnly,这2个注解只是声明这个public权限仅用于测试,并没有其它实际作用,在非测试类中一样可以调用这个public方法,靠开发自觉遵守声明
  • 通过反射调用私有方法(推荐)
//spring-test提供的工具类,参数分别是目标类实例、目标方法名、实参表,返回目标方法的返回值
T t = ReflectionTestUtils.invokeMethod(xxxServiceImpl, "methodName", args...);

 

常见问题

IDEA执行单元测试时报错

Error running ‘XxxTest.testXxx’: Command line is too long. Shorten command line for XxxTest.testXxx or also for JUnit default configuration?

可在父项目的 workspace.xml 中找到 <component name="PropertiesComponent">,加一个子元素

<property name="dynamic.classpath" value="true" />
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值