当前位置: 代码网 > it编程>编程语言>Java > Java单元测试实践(Mock)

Java单元测试实践(Mock)

2026年04月24日 Java 我要评论
概念单元测试,用于检查和验证程序中的各个单元(通常是函数、方法或类)是否按照预期工作(是否符合预期)。库库解释junit单元测试框架,提供了一组注解和断言来编写和运行测试spring test和spr

概念

单元测试,用于检查和验证程序中的各个单元(通常是函数、方法或类)是否按照预期工作(是否符合预期)。

解释
junit单元测试框架,提供了一组注解和断言来编写和运行测试
spring test和springboottest提供了一些方便的工具和注解来进行集成测试和组件测试。
assertj断言库,提供了丰富的断言来编写清晰、易读的测试代码。
hamcrest匹配器库,用于编写灵活和可读的断言。
mockito用于创建和管理模拟对象,帮助模拟外部依赖、行为和状态。

注解

  • @springboottest:用于加载spring应用程序上下文。
  • @autoconfiguremockmvc:用于自动配置mockmvc实例。
  • @transactional:开启事务功能。
  • @rollback()事务回滚,默认true。
  • @parameterizedtest :用于支持参数化测试@csvsource@valuesource@methodsource
  • @mock:创建模拟对象。
  • @mockbean:创建模拟对象,会注入到 spring 上下文。
  • @spy:创建真实对象,并可以部分模拟该对象的行为。
  • @injectmocks标记一个待测对象(被测试类的对象),用于注入被测试类中的依赖(注入模拟对象)

assertions类

junit测试中,assertions类提供了一系列用于验证测试结果的静态方法

  • assertequals(expected, actual):验证两个值是否相等。适用于比较基本数据类型、对象或数组等。
assertequals(5, result); // 比较整数值
assertequals("expected", result); // 比较字符串值
assertequals(expectedobject, actualobject); // 比较对象
assertequals(expectedarray, actualarray); // 比较数组
  • asserttrue(condition):验证给定的条件是否为真。
  • assertfalse(condition):验证给定的条件是否为假。
  • assertnull(object):验证给定对象是否为空。
  • assertnotnull(object):验证给定对象是否不为空。
  • assertsame(expected, actual):验证两个对象引用是否指向同一个对象。
  • assertnotsame(unexpected, actual):验证两个对象引用是否指向不同的对象。
  • assertthrows(expectedtype, executable):验证代码块是否抛出了指定类型的异常。

单元测试步骤

navigate → test :自动生成测试类。

注意controller层的单元测试,可以使用mockmvc模拟http请求。

  • 准备测试数据:在测试方法之前,准备好必要的测试数据,包括输入参数、模拟的依赖对象等。
  • 模拟依赖对象:使用mockito等框架模拟controllerservice层依赖的其他对象,例如repository、外部服务等。

若不使用模拟对象,直接@autowired注入测试即可。

  • 调用被测试的方法:在测试方法中调用controllerservice层的方法,传入准备好的测试数据。
  • 验证行为:使用断言验证方法的行为和返回结果是否符合预期

mock

在面向对象程序中,模拟对象(mock object)是以可控方式模拟真实对象行为假对象。

在编程过程中,通常通过模拟一些输入数据,来验证程序是否达到预期结果。

如果在单元测试中无法使用真实对象,可采用模拟对象进行替代。

mockmvc:模拟http请求

mockmvc spring提供的用于模拟http请求的工具,它允许模拟请求验证控制器的行为和响应。

在单元测试和集成测试中,mockmvc 可以用来测试控制器的端到端行为,而不需要启动整个应用程序服务器。

mockmvc构造

三种方法

  1. mockmvc = mockmvcbuilders.standalonesetup(new testontroller()).build();
  2. mockmvc = mockmvcbuilders.webappcontextsetup(webapplicationcontext).build();
  3. @autoconfiguremockmvc 注解用于自动配置 mockmvc实例。

mockmvc使用

mockmvc.perform执行一个请求,返回值resultactions

mockmvcrequestbuilders.get(“/xx/xx”)构造一个get请求。

  • mockmvcrequestbuilders类提供的各种静态方法构建不同类型的请求,如getpostputdelete等。
  • contenttype设置发送的数据格式
  • accept设置返回的数据格式
  • param添加请求传值
  • header设置请求头

resultactions.andexpect添加执行完成后的断言

  • 使用断言是判断结果是否符合期望
  • 使用mockmvcresultmatchers类提供的各种静态方法构建断言,例如status()content()header()等。
  • 使用mockmvcresultmatchers.status().isok()来断言预期的http状态码是否为200(ok)。

resultactions.anddo添加一个结果处理器,表示要对结果做点什么事情。比如处使用print()输出整个响应结果信息。

resultactions.andreturn表示执行完成后返回相应的结果

@mock

  • @mock 是 mockito 框架中的注解,用于创建模拟对象
  • @mock 只能用于普通的单元测试(例如,不涉及 spring 应用程序上下文的测试),通常与 mockitojunitrunnermockitoannotations.initmocks() 配合使用。
  • 它创建的模拟对象是纯粹的模拟对象,不会受到 spring 上下文的影响,因此不会自动注入到 spring 容器中。

@mockbean

  • @mockbean 是 spring boot test 模块中的注解,用于创建模拟对象,并将其注入到 spring 上下文中,以便在集成测试中使用。
  • @mockbean 可以用于测试 spring 上下文中的组件,例如服务、存储库、控制器等。
  • 它创建的模拟对象是由 spring 管理的 bean,可以被自动注入到其他 spring bean 中

@mock和@mockbean区别(是否注入)

  • @mock 用于创建纯粹的模拟对象
  • @mockbean 用于在 spring 上下文中创建模拟对象,并将其注入到其他 spring bean 中,以便在集成测试中使用。

@spy

@spy 是 mockito 框架中的一个注解,用于创建一个真实对象,并部分模拟该对象的行为。

@mock 注解不同,@spy 注解创建的对象是真实对象,但可以选择性地模拟部分方法的行为。

@injectmocks和@mock

  • @injectmocks :标记一个待测对象(被测试类的对象),用于注入被测试类中的依赖
  • @mock 用于创建模拟对象@injectmocks 用于将这些 模拟对象 注入被测试对象中,以便进行单元测试。

@parameterizedtest注解

用于支持参数化测试。为测试方法提供一组不同的参数,以便多次运行相同的测试逻辑,但使用不同的输入参数

@csvsource

用于提供一组参数给参数化测试方法。使用逗号分隔的字符串表示多个参数,每个字符串代表一个测试案例。

@parameterizedtest
@csvsource({"1, 1, 2", "2, 3, 5", "5, 5, 10"})
void testaddition(int a, int b, int expectedsum) {
    int actualsum = a + b;
assertequals(expectedsum, actualsum, "sum of " + a + " and " + b + " should be " + expectedsum);
}

@parameterizedtest 注解表示该方法是一个参数化测试方法。

@csvsource 注解提供了一组参数,每一行代表一个测试案例。

  • 在这个示例中,提供了三组参数,每组参数包含两个整数和一个预期的结果。
  • 参数化测试方法 testaddition() 接受三个参数:两个整数和一个预期的结果。

测试方法将对这些参数执行加法操作,并使用断言验证实际的结果是否与预期的结果相匹配。

@valuesource

用于提供基本类型字符串类型参数逗号分隔多个参数,每个参数代表一个测试案例。

@parameterizedtest
@valuesource(ints = {1, 2, 3})
void testispositive(int number) {
//验证参数是否为正数
asserttrue(number > 0);
}

@methodsource

用于指定一个方法提供参数给参数化测试方法。

@methodsource 注解,可以将参数提供逻辑从测试类中抽取到一个单独的方法中,以提高代码的可读性和可维护性。

@parameterizedtest
@methodsource("stringprovider")
void teststringlength(string input, int expectedlength) {
assertequals(expectedlength, input.length());
}
// 参数提供逻辑 抽取到 一个单独的方法
static stream<arguments> stringprovider() {
    return stream.of(
            arguments.of("apple", 5),
            arguments.of("banana", 6),
            arguments.of("orange", 6)
    );
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com