单元测试Junit5
JUnit 5 =
<dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <version>5.5.2</version> <scope>test</scope> </dependency> <dependency> <groupId>org.junit.platform</groupId> <artifactId>junit-platform-launcher</artifactId> <version>1.6.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> <version>5.5.2</version> <scope>test</scope> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-junit-jupiter</artifactId> <version>3.5.15</version> <scope>test</scope> </dependency>
注解
常用注解
-
@Test 表示方法是一种测试方法。 与JUnit 4的@Test注解不同,此注释不会声明任何属性。
-
@ParameterizedTest 表示方法是参数化测试
-
@RepeatedTest 表示方法是重复测试模板
-
@TestFactory 表示方法是动态测试的测试工程
-
@DisplayName 为测试类或者测试方法自定义一个名称
-
@BeforeEach 表示方法在每个测试方法运行前都会运行 ,@AfterEach 表示方法在每个测试方法运行之后都会运行
-
@BeforeAll 表示方法在所有测试方法之前运行 ,@AfterAll 表示方法在所有测试方法之后运行
-
@Nested 表示带注解的类是嵌套的非静态测试类,@BeforeAll和@AfterAll方法不能直接在@Nested测试类中使用,除非修改测试实例生命周期。
-
@Tag 用于在类或方法级别声明用于过滤测试的标记
-
@Disabled 用于禁用测试类或测试方法
-
@ExtendWith 用于注册自定义扩展,该注解可以继承
-
@FixMethodOrder(MethodSorters.NAME_ASCENDING),控制测试类中方法执行的顺序,这种测试方式将按方法名称的进行排序,由于是按字符的字典顺序,所以以这种方式指定执行顺序会始终保持一致;不过这种方式需要对测试方法有一定的命名规则,如 测试方法均以testNNN开头(NNN表示测试方法序列号 001-999)
常用断言 Assertions
-
assertEquals 断言预期值和实际值相等
-
assertAll 分组断言,执行其中包含的所有断言
-
assertArrayEquals 断言预期数组和实际数组相等
-
assertFalse 断言条件为假
-
assertNotNull 断言不为空
-
assertSame 断言两个对象相等
-
assertTimeout 断言超时
-
fail 使单元测试失败
MockMvc
MockMvc是由spring-test包/Junit5提供,实现了对Http请求的模拟,能够直接使用网络的形式,转换到Controller的调用,使得测试速度快、不依赖网络环境。同时提供了一套验证的工具,结果的验证十分方便。
-
mock接口/类,验证,测试桩
LinkedList mockedList = Mockito.mock(LinkedList.class); mockedList.add("one"); //验证 Mockito.verify(mockedList).add("one"); //测试桩 //当调用mockList.get(0)的时候,返回first //当调用mockList.get(1)的时候,抛出一个运行时异常 when(mockedList.get(0)).thenReturn("first"); when(mockedList.get(1)).thenThrow(new RuntimeException());
-
使用mock进行接口测试
@RunWith(SpringJUnit4ClassRunner.class) //表示继承了SpringJUnit4ClassRunner类 @ContextConfiguration(locations = {"classpath:applicationContext.xml"}) public class UserTest { private MockMvc mockMvc; @Autowired private WebApplicationContext webApplicationContext; @Before public void setup() { mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); } @Test public void test() throws Exception { /* * 1、mockMvc.perform执行一个请求。 * 2、MockMvcRequestBuilders.get("XXX")构造一个请求。 * 3、ResultActions.param添加请求传值 * 4、ResultActions.accept(MediaType.TEXT_HTML_VALUE))设置返回类型 * 5、ResultActions.andExpect添加执行完成后的断言。 * 6、ResultActions.andDo添加一个结果处理器,表示要对结果做点什么事情 * 比如此处使用MockMvcResultHandlers.print()输出整个响应结果信息。 * 7、ResultActions.andReturn表示执行完成后返回相应的结果。 */ mockMvc.perform(MockMvcRequestBuilders .get("/user") .accept(MediaType.APPLICATION_JSON_VALUE) .param("id", "2")) .andExpect(MockMvcResultMatchers.status().isOk()) .andExpect(MockMvcResultMatchers.content().string("Hello Tom!")) .andDo(MockMvcResultHandlers.print()); } }
mockBean
-
@MockBean
使用 @MockBean 注入这个bean,并设置mock规则,可不运行原有逻辑而运行设置的规则
-
@SpyBean
介于 @Autowired 和 @MockBean 之间,有设置规则就按设置的规则运行,没有设置规则就按原有的逻辑运行
@Service public class Ser1 { @Autowired private Ser2 ser2; public int sub(int a,int b){ return a-b; } public int add(int a,int b){ return ser2.add(a,b); } public int mult(int a,int b){ return a*b; } } @Service public class Ser2 { public int add(int a,int b){ return a+b; } } @SpringBootTest public class Ser1Test { // 使用 @MockBean 注入 @MockBean private Ser1 ser1; // 使用 @Autowired 注入 @Autowired private Ser2 ser2; @Test public void test(){ // 设置 sub 方法的mock规则 when(ser1.sub(3,1)).thenReturn(1); int res1=ser1.sub(3,1); // 根据mock规则,res1=1 Assertions.assertEquals(res1,2); // 断言错误 // 测试 ser1.add(),实际运行的是 ser2.add(),ser2未mock,按原有逻辑运行 int res2=ser1.add(1,1); Assertions.assertEquals(res2,2); } }
参考 https://zhuanlan.zhihu.com/p/55648107
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具