java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java单元测试(Mock)

Java单元测试实践(Mock)

作者:鲁班班

本文介绍了单元测试、JUnit、Spring相关注解、Mockito、断言库的使用方法,涵盖MockMvc、@Mock、@MockBean、@Spy、@InjectMocks、@ParameterizedTest、@CsvSource、@ValueSource、@MethodSource等,介绍了Mock的概念及用途,重点讲解了单元测试的步骤、MockMvc的使用

概念

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

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

注解

Assertions类

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

assertEquals(5, result); // 比较整数值
assertEquals("expected", result); // 比较字符串值
assertEquals(expectedObject, actualObject); // 比较对象
assertEquals(expectedArray, actualArray); // 比较数组

单元测试步骤

Navigate → Test :自动生成测试类。

注意Controller层的单元测试,可以使用MockMvc模拟HTTP请求。

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

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请求。

ResultActions.andExpect添加执行完成后的断言

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

ResultActions.andReturn表示执行完成后返回相应的结果

@Mock

@MockBean

@Mock和@MockBean区别(是否注入)

@Spy

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

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

@InjectMocks和@Mock

@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 注解提供了一组参数,每一行代表一个测试案例。

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

@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)
    );
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文