junit单元测试示例

本文最后更新于:2025年2月18日 下午

junit单元测试

junit4单元测试示例

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
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@ActiveProfiles("dev") // 用于指定测试环境,以避免生产环境下打包时运行此测试从而产生访问不到数据库的错误
@RunWith(SpringRunner.class) // 使用 Spring 的测试运行器
// 不会启动 Web 环境,适用于非 Web 服务的集成测试
@SpringBootTest
// 模拟 Web 环境,适用于 Web 层的控制器、过滤器等测试,但没有启动实际的 Web 服务器。
//@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
// 启动实际的 Web 服务器,使用配置文件中定义的端口进行测试。
//@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
// 启动实际的 Web 服务器,随机分配一个可用端口,适用于测试真实的 Web 请求和响应。
// @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class HelloControllerTests {

@Autowired
private UserMapper userMapper;

@Test
public void testHello() {
User user = userMapper.selectByUsername("1");
System.out.println(user);
}
}

junit5单元测试示例

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
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@ActiveProfiles("dev") // 用于指定测试环境,以避免生产环境下打包时运行此测试从而产生访问不到数据库的错误
// 不会启动 Web 环境,适用于非 Web 服务的集成测试
@SpringBootTest
// 模拟 Web 环境,适用于 Web 层的控制器、过滤器等测试,但没有启动实际的 Web 服务器。
//@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
// 启动实际的 Web 服务器,使用配置文件中定义的端口进行测试。
//@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
// 启动实际的 Web 服务器,随机分配一个可用端口,适用于测试真实的 Web 请求和响应。
// @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class HelloControllerTests {

@Autowired
private UserMapper userMapper;

@Test
public void testHello() {
User user = userMapper.selectByUsername("1");
System.out.println(user);
}
}


尽可能用到更多junit功能的测试示例

JUnit 5 示例代码

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import org.junit.jupiter.api.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.condition.*;
import org.junit.jupiter.params.*;
import org.junit.jupiter.params.provider.*;

import java.util.stream.Stream;

public class JUnit5ExampleTest {

// 1. 定义一个测试前后的生命周期方法

@BeforeAll // 所有测试方法执行之前执行一次的静态方法
static void beforeAll() {
System.out.println("Before All Tests");
}

@AfterAll // 在所有测试方法执行完毕之后执行一次的静态方法
static void afterAll() {
System.out.println("After All Tests");
}

@BeforeEach // 每个测试方法执行之前执行
void beforeEach() {
System.out.println("Before Each Test");
}

@AfterEach // 每个测试方法执行之后执行
void afterEach() {
System.out.println("After Each Test");
}

// 2. 一个简单的测试,断言是否相等
// 断言是为了确保代码按预期运行,而默认的行为是 静默成功 和 失败时输出错误
@Test
void simpleTest() {
int sum = 2 + 3;
assertEquals(5, sum, "Sum should be 5");
}

// 3. 断言失败的测试
@Test
void failedTest() {
int product = 3 * 3;
assertNotEquals(10, product, "Product should not be 10");
}

// 4. 测试异常抛出
@Test
void exceptionTest() {
Exception exception = assertThrows(ArithmeticException.class, () -> {
int result = 10 / 0;
});
assertEquals("/ by zero", exception.getMessage());
}

// 5. 条件化测试(例如:只有在 Linux 系统上才会运行)
@Test
@EnabledOnOs(OS.LINUX)
void testOnLinux() {
System.out.println("Running test on Linux OS");
}

@Test
@EnabledOnOs(OS.WINDOWS)
void testOnWindows() {
System.out.println("Running test on Windows OS");
}

// 6. 参数化测试 - 使用不同的输入进行多次测试
@ParameterizedTest
@ValueSource(ints = {1, 2, 3})
void parameterizedTestWithValueSource(int number) {
assertTrue(number > 0, "Number should be greater than 0");
}

// 7. 参数化测试 - 使用方法提供参数
@ParameterizedTest
@MethodSource("provideNumbersForMultiplication")
void parameterizedTestWithMethodSource(int number1, int number2, int expectedResult) {
assertEquals(expectedResult, number1 * number2);
}

private static Stream<Arguments> provideNumbersForMultiplication() {
return Stream.of(
Arguments.of(2, 3, 6),
Arguments.of(3, 5, 15),
Arguments.of(4, 6, 24)
);
}

// 8. 动态测试(动态生成的测试用例)
@TestFactory
Stream<DynamicTest> dynamicTests() {
return Stream.of(
DynamicTest.dynamicTest("Test 1", () -> assertEquals(1, 1)),
DynamicTest.dynamicTest("Test 2", () -> assertEquals(2, 2))
);
}

// 9. 快速失败的测试 - 确保一旦测试失败立即停止
@Test
@Tag("fastFail")
void fastFailTest() {
assertTrue(false, "This test should fail and stop immediately");
}

// 10. 分组标记测试 - 用 @Tag 来标记测试的类别
@Test
@Tag("unit")
void unitTest() {
assertTrue(true, "This is a unit test");
}

@Test
@Tag("integration")
void integrationTest() {
assertTrue(true, "This is an integration test");
}

// 11. 使用注解标注测试条件 - 条件注解
@Test
@EnabledIfSystemProperty(named = "os.name", matches = ".*Windows.*")
void testOnlyForWindows() {
System.out.println("This test will run only on Windows");
}
}

解释

  1. 生命周期方法 (@BeforeAll, @AfterAll, @BeforeEach, @AfterEach):
    • @BeforeAll: 在所有测试方法执行之前执行一次的静态方法。
    • @AfterAll: 在所有测试方法执行完毕之后执行一次的静态方法。
    • @BeforeEach: 每个测试方法执行之前执行。
    • @AfterEach: 每个测试方法执行完毕之后执行。
  2. 断言 (assertEquals, assertNotEquals, assertTrue, assertThrows):
    • assertEqualsassertNotEquals: 用于断言预期结果与实际结果是否一致。
    • assertThrows: 用于验证是否抛出了预期的异常。
  3. 条件化测试 (@EnabledOnOs, @EnabledIfSystemProperty):
    • @EnabledOnOs: 只有在特定操作系统上才会运行此测试。
    • @EnabledIfSystemProperty: 根据系统属性的值来决定是否执行此测试。
  4. 参数化测试 (@ParameterizedTest, @ValueSource, @MethodSource):
    • @ParameterizedTest: 指定这是一个参数化的测试。
    • @ValueSource: 使用不同的值进行多次测试。
    • @MethodSource: 使用方法来提供参数。
  5. 动态测试 (@TestFactory, DynamicTest):
    • 使用 @TestFactory 注解来创建动态生成的测试用例,可以根据需要动态地生成多个测试用例。
  6. 快速失败的测试 (@Tag):
    • 使用 @Tag 可以为测试分类,并用 @Tag("fastFail") 快速标记失败测试。

junit单元测试示例
https://superlovelace.top/2024/11/14/junit单元测试/
作者
棱境
发布于
2024年11月14日
更新于
2025年2月18日
许可协议