前言
最近写很多单元测试 一直没记录
今天整理一下 常见的demo 方便后续速查
https://junit.org/junit5/docs/current/user-guide/#overview
JUnit5注解汇总
基础测试控制
注解 |
含义 |
使用场景 |
@Test |
标记测试方法 |
单个测试逻辑的验证 |
@BeforeEach |
每个测试方法前执行 |
初始化测试环境 |
@AfterEach |
每个测试方法后执行 |
清理测试环境 |
@BeforeAll |
整个测试类执行前运行 |
初始化全局资源 |
@AfterAll |
整个测试类执行后运行 |
清理全局资源 |
@Disabled |
禁用测试方法 |
暂时跳过测试 |
@Tag |
标记测试,支持按标签执行 |
组织和筛选测试 |
@DisplayName |
设置显示名称 |
提高测试输出可读性 |
参数化测试
注解 |
含义 |
使用场景 |
@ParameterizedTest |
参数化的测试 |
验证不同输入值的行为 |
@ValueSource |
提供固定值作为参数 |
参数列表 |
@EnumSource |
提供枚举值作为参数 |
枚举遍历 |
@CsvSource / @CsvFileSource |
CSV数据作为参数 |
数据驱动测试 |
测试控制和异常测试
注解 |
含义 |
使用场景 |
@RepeatedTest |
重复执行测试 |
验证稳定性 |
@AssertThrows |
验证方法抛出预期异常 |
异常处理测试 |
扩展和定制
注解 |
含义 |
使用场景 |
@TestExtension |
定义测试扩展 |
自定义测试行为 |
@RegisterExtension |
注册测试扩展 |
使用自定义扩展 |
@TempDir |
提供临时目录 |
存储临时文件 |
@Import |
引入额外配置类 |
测试上下文扩展 |
mockito
注解 |
作用 |
使用场景 |
@Mock |
创建一个模拟对象,可以控制其行为和返回值。 |
当需要隔离测试,不依赖真实对象时。 |
@Spy |
创建一个真实对象的代理,可以部分模拟,其他行为保持不变。 |
当需要测试部分真实行为,同时控制某些方法时。 |
@InjectMocks |
自动注入依赖,通常用于创建被测试对象,其中依赖项由@Mock 或@Spy 注解的实例填充。 |
当测试类需要依赖模拟对象时。 |
@Captor |
配合ArgumentCaptor 使用,捕获方法调用的参数。 |
当需要验证方法调用的参数时。 |
@RunWith(MockitoJUnitRunner.class) |
使用Mockito运行器,初始化@Mock 和@Spy 注解的实例。 |
在JUnit测试类中使用,代替@Before 初始化模拟对象。 |
@Before |
初始化方法,通常用于配置模拟对象。 |
需要在每个测试方法之前执行的初始化逻辑。 |
@After |
清理方法,通常用于清理模拟对象。 |
需要在每个测试方法之后执行的清理逻辑。 |
@MockBean |
Spring Boot测试中创建模拟的Spring Bean。 |
当测试需要模拟Spring容器中的Bean时。 |
@SpyBean |
Spring Boot测试中创建真实Bean的代理,可以部分模拟。 |
当测试需要部分模拟Spring容器中的Bean时。 |
@WithMockUser |
Spring Security测试中模拟登录用户的身份。 |
当测试需要模拟不同用户权限时。 |
@MockitoSettings |
控制Mockito框架的全局设置,如严格性、默认答案等。 |
当需要自定义Mockito的行为时。 |
@ExtendWith(MockitoExtension.class) |
JUnit 5中初始化Mockito,替代@RunWith(MockitoJUnitRunner.class) 。 |
在JUnit 5测试类中使用。 |
Mockito 主要类和函数
Mockito 类与函数
类名 |
函数 |
描述 |
Mockito |
mock(Class<T> classToMock) |
创建模拟对象,不执行实际操作。 |
|
when(T toMock) |
定义模拟对象的行为,设置方法调用的返回值或行为。 |
|
thenReturn(T value) |
模拟方法调用时返回指定值。 |
|
thenThrow(Throwables... toThrow) |
模拟方法调用时抛出异常。 |
|
doAnswer(Answer answer) |
自定义方法调用的处理逻辑。 |
|
doNothing() |
方法调用不执行任何操作,不返回值。 |
|
doCallRealMethod() |
使模拟方法调用实际实现。 |
|
verify(T mock) |
验证模拟对象的方法是否被调用。 |
|
verifyNoMoreInteractions(Object... mocks) |
验证没有其他未验证的交互。 |
|
verifyZeroInteractions(Object... mocks) |
验证模拟对象未被调用。 |
ArgumentMatchers 辅助类
函数 |
描述 |
any() |
匹配任何参数值。 |
anyVararg() |
匹配任何变长参数。 |
eq(T value) |
匹配与给定值相等的参数。 |
Assertions 主要方法
JUnit Jupiter (org.junit.jupiter.api.Assertions
)
方法 |
描述 |
assertEquals(expected, actual) |
验证预期值与实际值相等。 |
assertNotEquals(expected, actual) |
验证预期值与实际值不相等。 |
assertTrue(condition) |
验证条件为真。 |
assertFalse(condition) |
验证条件为假。 |
assertNull(object) |
验证对象为 null。 |
assertNotNull(object) |
验证对象非 null。 |
assertSame(expected, actual) |
验证预期对象与实际对象是同一个对象。 |
assertNotSame(expected, actual) |
验证预期对象与实际对象不是同一个对象。 |
assertAll(Executable... executables) |
批量执行多个断言。 |
示例
- 基本依赖 starter包包含了 junit5和mockito
1
| testImplementation "org.springframework.boot:spring-boot-starter-test"
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| package com.ming;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class) public class DemoTest { @BeforeEach public void init() { System.out.println("init"); }
@AfterEach public void destroy() { System.out.println("destroy"); }
@Test public void test() { System.out.println("test"); } }
|
mock静态方法 以前是用powermock junit5之后 mockito也提供mock的方式
1 2
| testImplementation group: 'org.mockito', name: 'mockito-inline', version: '5.2.0'
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.MockedStatic; import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals;
@ExtendWith(SpringExtension.class) public class MockStaticTest { private MockedStatic<StaticTestService> mockStatic; @BeforeEach public void setUp() { mockStatic = org.mockito.Mockito.mockStatic(StaticTestService.class); }
@AfterEach public void tearDown() { mockStatic.close(); }
@Test public void testNoArg() { mockStatic.when(StaticTestService::testNoArg).thenReturn("test"); assertEquals("test", StaticTestService.testNoArg()); }
@Test public void testArg() { mockStatic.when(() -> StaticTestService.testArg("arg")).thenReturn("test"); assertEquals("test", StaticTestService.testArg("arg")); assertNotEquals("test", StaticTestService.testArg("arg1")); } }
class StaticTestService { public static String testNoArg() { return "????"; }
public static String testArg(String str) { return "????"; } }
|
ReflectionTestUtils.setField(testService, “字段名”, “字段赋值”);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.util.ReflectionTestUtils;
import static org.junit.jupiter.api.Assertions.assertEquals;
@ExtendWith(SpringExtension.class) public class MockTest { @InjectMocks private TestService testService;
@Test public void test() { assertEquals("????ming-default", testService.getStr()); ReflectionTestUtils.setField(testService, "str", "ming-update"); assertEquals("????ming-update", testService.getStr()); } }
class TestService { private String str = "ming-default";
public String getStr() { return "????" + str; } }
|
- mock MybatisPlus Mapper
如果用到lambdaXXXXX 需要注入 TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), “”), xxxxEntity.class);
总结
就是常见的单元测试方法
junit5 已经成为一个java的单元测试平台了
常见的操作 基本覆盖
配合mockito基本够用