Files

246 lines
19 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 代码审查报告
**文件:** `data\demo-pmd\src\com\demo\errorprone\extra\JUnit4RulesTest.java`
**语言:** java
**耗时:** 228.6s
**分析工具:** pmd
---
总计: 74 | 错误: 12 | 警告: 62 | 建议: 0
静态分析 · 67 个问题
- 🔴 `pmd:WrongTestAnnotation` L11
org.junit.Test 是 JUnit 4 的注解,而当前代码库正在使用 JUnit Jupiter。
建议: 将导入改为 org.junit.jupiter.api.TestJUnit 5),并同步将 org.junit.Assert 迁移为 org.junit.jupiter.api.Assertions。
- 🔴 `pmd:WrongTestAnnotation` L19
org.junit.Test 是 JUnit 4 的注解,而当前代码库正在使用 JUnit Jupiter。
建议: 将导入改为 org.junit.jupiter.api.TestJUnit 5),并同步将 org.junit.Assert 迁移为 org.junit.jupiter.api.Assertions。
- 🔴 `pmd:WrongTestAnnotation` L25
org.junit.Test 是 JUnit 4 的注解,而当前代码库正在使用 JUnit Jupiter。
建议: 将导入改为 org.junit.jupiter.api.TestJUnit 5),并同步将 org.junit.Assert 迁移为 org.junit.jupiter.api.Assertions。
- 🔴 `pmd:WrongTestAnnotation` L39
org.junit.Test 是 JUnit 4 的注解,而当前代码库正在使用 JUnit Jupiter。
建议: 将导入改为 org.junit.jupiter.api.TestJUnit 5),并同步将 org.junit.Assert 迁移为 org.junit.jupiter.api.Assertions。
- 🔴 `pmd:WrongTestAnnotation` L47
org.junit.Test 是 JUnit 4 的注解,而当前代码库正在使用 JUnit Jupiter。
建议: 将导入改为 org.junit.jupiter.api.TestJUnit 5),并同步将 org.junit.Assert 迁移为 org.junit.jupiter.api.Assertions。
- 🔴 `pmd:WrongTestAnnotation` L53
org.junit.Test 是 JUnit 4 的注解,而当前代码库正在使用 JUnit Jupiter。
建议: 将导入改为 org.junit.jupiter.api.TestJUnit 5),并同步将 org.junit.Assert 迁移为 org.junit.jupiter.api.Assertions。
- 🔴 `pmd:AvoidThrowingNullPointerException` L63
避免抛出空指针异常。
建议: 不要显式 throw new NullPointerException();可改用 java.util.Objects.requireNonNull(null) 产生 NPE,或改抛更具体的异常并同步调整测试期望。
- 🔴 `pmd:WrongTestAnnotation` L69
org.junit.Test 是 JUnit 4 的注解,而当前代码库正在使用 JUnit Jupiter。
建议: 将导入改为 org.junit.jupiter.api.TestJUnit 5),并同步将 org.junit.Assert 迁移为 org.junit.jupiter.api.Assertions。
- 🔴 `pmd:WrongTestAnnotation` L79
org.junit.Test 是 JUnit 4 的注解,而当前代码库正在使用 JUnit Jupiter。
建议: 将导入改为 org.junit.jupiter.api.TestJUnit 5),并同步将 org.junit.Assert 迁移为 org.junit.jupiter.api.Assertions。
- 🟡 `pmd:AtLeastOneConstructor` L9
每个类都应声明至少一个构造函数。
建议: 为 JUnit4RulesTest 添加一个显式构造函数,避免依赖隐式公有无参构造器。
- 🟡 `pmd:LocalVariableCouldBeFinal` L13
局部变量 'a' 可以声明为 final。
建议: 将该局部变量标记为 final,防止意外重新赋值并提升可读性。
- 🟡 `pmd:LocalVariableCouldBeFinal` L14
局部变量 'b' 可以声明为 final。
建议: 将该局部变量标记为 final,防止意外重新赋值并提升可读性。
- 🟡 `pmd:SimplifiableTestAssertion` L15
该断言可以使用 assertEquals 简化。
建议: 用 assertEquals(a, b) 代替 assertTrue(a.equals(b)),并补充失败消息;若迁移到 JUnit Jupiter,应为 Assertions.assertEquals(a, b)。
- 🟡 `pmd:UnitTestAssertionsShouldIncludeMessage` L15
单元测试断言应包含失败消息。
建议: 为断言增加第一个 String 参数作为失败消息,例如 assertEquals("a should equal b", a, b)。
- 🟡 `pmd:UnitTestAssertionsShouldIncludeMessage` L21
单元测试断言应包含失败消息。
建议: 为 assertEquals 补充失败消息,例如 assertEquals("expected value", expected, actual)。
- 🟡 `pmd:UnitTestContainsTooManyAsserts` L26
单元测试不应包含超过 1 个断言。
建议: 将 testTooMany 拆分为多个测试方法,每个方法只保留一个断言;或使用 AssertJ 的软断言(assertSoftly)承载多个校验。
- 🟡 `pmd:UnitTestAssertionsShouldIncludeMessage` L27
单元测试断言应包含失败消息。
建议: 该断言本身无意义,建议删除;如果保留,必须提供消息,例如 assertTrue("message", condition)。
- 🟡 `pmd:UnnecessaryBooleanAssertion` L27
assertTrue(true) 或类似语句是不必要的。
建议: 删除对布尔常量 true 的断言;若需要固定验证,应改为对实际被测状态的断言。
- 🟡 `pmd:UnitTestAssertionsShouldIncludeMessage` L28
单元测试断言应包含失败消息。
建议: 该断言本身无意义,建议删除;如果保留,必须提供消息,例如 assertTrue("message", condition)。
- 🟡 `pmd:UnnecessaryBooleanAssertion` L28
assertTrue(true) 或类似语句是不必要的。
建议: 删除对布尔常量 true 的断言;若需要固定验证,应改为对实际被测状态的断言。
- 🟡 `pmd:UnitTestAssertionsShouldIncludeMessage` L29
单元测试断言应包含失败消息。
建议: 该断言本身无意义,建议删除;如果保留,必须提供消息,例如 assertTrue("message", condition)。
- 🟡 `pmd:UnnecessaryBooleanAssertion` L29
assertTrue(true) 或类似语句是不必要的。
建议: 删除对布尔常量 true 的断言;若需要固定验证,应改为对实际被测状态的断言。
- 🟡 `pmd:UnitTestAssertionsShouldIncludeMessage` L30
单元测试断言应包含失败消息。
建议: 该断言本身无意义,建议删除;如果保留,必须提供消息,例如 assertTrue("message", condition)。
- 🟡 `pmd:UnnecessaryBooleanAssertion` L30
assertTrue(true) 或类似语句是不必要的。
建议: 删除对布尔常量 true 的断言;若需要固定验证,应改为对实际被测状态的断言。
- 🟡 `pmd:UnitTestAssertionsShouldIncludeMessage` L31
单元测试断言应包含失败消息。
建议: 为 assertEquals 增加失败消息,例如 assertEquals("1 should equal 1", 1, 1)。
- 🟡 `pmd:UnitTestAssertionsShouldIncludeMessage` L32
单元测试断言应包含失败消息。
建议: 为 assertEquals 增加失败消息,例如 assertEquals("2 should equal 2", 2, 2)。
- 🟡 `pmd:UnitTestAssertionsShouldIncludeMessage` L33
单元测试断言应包含失败消息。
建议: 为 assertEquals 增加失败消息,例如 assertEquals("3 should equal 3", 3, 3)。
- 🟡 `pmd:UnitTestAssertionsShouldIncludeMessage` L34
单元测试断言应包含失败消息。
建议: 为 assertEquals 增加失败消息,例如 assertEquals("4 should equal 4", 4, 4)。
- 🟡 `pmd:UnitTestAssertionsShouldIncludeMessage` L35
单元测试断言应包含失败消息。
建议: 为 assertEquals 增加失败消息,例如 assertEquals("5 should equal 5", 5, 5)。
- 🟡 `pmd:LocalVariableCouldBeFinal` L41
局部变量 'actual' 可以声明为 final。
建议: 将该局部变量标记为 final,防止意外重新赋值并提升可读性。
- 🟡 `pmd:LocalVariableCouldBeFinal` L42
局部变量 'expected' 可以声明为 final。
建议: 将该局部变量标记为 final,防止意外重新赋值并提升可读性。
- 🟡 `pmd:UnitTestAssertionsShouldIncludeMessage` L43
单元测试断言应包含失败消息。
建议: 为 assertEquals 增加失败消息,并同时修正参数顺序:assertEquals("expected should equal actual", expected, actual)。
- 🟡 `pmd:UnitTestAssertionsShouldIncludeMessage` L49
单元测试断言应包含失败消息。
建议: 该断言本身无意义,建议删除;如果保留,必须提供消息,例如 assertTrue("message", condition)。
- 🟡 `pmd:UnnecessaryBooleanAssertion` L49
assertTrue(true) 或类似语句是不必要的。
建议: 删除对布尔常量 true 的断言;若需要固定验证,应改为对实际被测状态的断言。
- 🟡 `pmd:JUnitUseExpected` L55
在 JUnit4 中,应使用 @Test(expected) 标注预期会抛出异常的测试。
建议: 若使用 JUnit 4,改为 @Test(expected = NullPointerException.class) 并删除 try/catch;若已迁移到 JUnit Jupiter,使用 assertThrows(NullPointerException.class, () -> doSomething())。
- 🟡 `pmd:EmptyCatchBlock` L58
避免空 catch 块。
建议: 不要在 catch 块中留空;应使用 assertThrows 或 @Test(expected) 声明预期异常,或至少记录异常并重新抛出。
- 🟡 `pmd:AvoidCatchingGenericException` L58
避免在 try-catch 块中捕获 NullPointerException。
建议: 不要捕获并吞掉 NPE;在 JUnit Jupiter 下应使用 assertThrows 声明预期异常,而非手写 try/catch。
- 🟡 `pmd:AtLeastOneConstructor` L68
每个类都应声明至少一个构造函数。
建议: 为 MissingAfterTest 添加一个显式构造函数。
- 🟡 `pmd:PublicMemberInNonPublicType` L70
公共成员 'testCleanup' 声明在非公共类型中。
建议: 如果使用 JUnit Jupiter,可去掉 public 修饰;如果保留 JUnit 4,应将测试类声明为 public。
- 🟡 `pmd:UnitTestAssertionsShouldIncludeMessage` L71
单元测试断言应包含失败消息。
建议: 该断言本身无意义,建议删除;如果保留,必须提供消息,例如 assertTrue("message", condition)。
- 🟡 `pmd:UnnecessaryBooleanAssertion` L71
assertTrue(true) 或类似语句是不必要的。
建议: 删除对布尔常量 true 的断言;若需要固定验证,应改为对实际被测状态的断言。
- 🟡 `pmd:UnitTestShouldUseAfterAnnotation` L73
如果此方法用于测试清理,请使用正确的注解。
建议: 在 JUnit Jupiter 中使用 @AfterEach,在 JUnit 4 中使用 @After,并补充清理逻辑或删除空方法。
- 🟡 `pmd:DetachedTestCase` L73
可能是脱离的 JUnit 测试用例。
建议: 该方法名容易让 JUnit 误认为它是测试用例,但未使用生命周期注解;如果用于清理,请添加 @AfterEach/@After;否则删除或重命名。
- 🟡 `pmd:PublicMemberInNonPublicType` L73
公共成员 'tearDown' 声明在非公共类型中。
建议: 如果使用 JUnit Jupiter,可去掉 public 修饰;如果保留 JUnit 4,应将测试类声明为 public。
- 🟡 `pmd:AtLeastOneConstructor` L78
每个类都应声明至少一个构造函数。
建议: 为 MissingBeforeTest 添加一个显式构造函数。
- 🟡 `pmd:PublicMemberInNonPublicType` L80
公共成员 'testSetup' 声明在非公共类型中。
建议: 如果使用 JUnit Jupiter,可去掉 public 修饰;如果保留 JUnit 4,应将测试类声明为 public。
- 🟡 `pmd:UnitTestAssertionsShouldIncludeMessage` L81
单元测试断言应包含失败消息。
建议: 该断言本身无意义,建议删除;如果保留,必须提供消息,例如 assertTrue("message", condition)。
- 🟡 `pmd:UnnecessaryBooleanAssertion` L81
assertTrue(true) 或类似语句是不必要的。
建议: 删除对布尔常量 true 的断言;若需要固定验证,应改为对实际被测状态的断言。
- 🟡 `pmd:UnitTestShouldUseBeforeAnnotation` L83
如果此方法用于测试初始化,请使用正确的注解。
建议: 在 JUnit Jupiter 中使用 @BeforeEach,在 JUnit 4 中使用 @Before,并补充初始化逻辑或删除空方法。
- 🟡 `pmd:DetachedTestCase` L83
可能是脱离的 JUnit 测试用例。
建议: 该方法名容易让 JUnit 误认为它是测试用例,但未使用生命周期注解;如果用于初始化,请添加 @BeforeEach/@Before;否则删除或重命名。
- 🟡 `pmd:PublicMemberInNonPublicType` L83
公共成员 'setUp' 声明在非公共类型中。
建议: 如果使用 JUnit Jupiter,可去掉 public 修饰;如果保留 JUnit 4,应将测试类声明为 public。
- 🟡 `pmd:AtLeastOneConstructor` L88
每个类都应声明至少一个构造函数。
建议: 为 MissingTestAnnotationTest 添加一个显式构造函数。
- 🟡 `pmd:TestClassWithoutTestCases` L88
类 'MissingTestAnnotationTest' 可能是测试类,但它不包含任何测试用例。
建议: 为该类添加一个带断言且标注 @Test 的测试方法;若只是 PMD 反例,可删除该类。
- 🟡 `pmd:PublicMemberInNonPublicType` L89
公共成员 'testSomething' 声明在非公共类型中。
建议: 如果使用 JUnit Jupiter,可去掉 public 修饰;如果保留 JUnit 4,应将测试类声明为 public。
- 🟡 `pmd:UnitTestShouldUseTestAnnotation` L89
单元测试应使用 @Test 注解,否则不会运行;在 JUnit Jupiter 中也可以使用 @RepeatedTest@TestFactory@TestTemplate@ParameterizedTest
建议: 在 testSomething 方法上添加 @org.junit.jupiter.api.Test(如果迁移到 Jupiter)或 org.junit.Test(如果保留 JUnit 4),并在方法内补充断言。
- 🟡 `pmd:AtLeastOneConstructor` L94
每个类都应声明至少一个构造函数。
建议: 为 SpellingTest 添加一个显式构造函数。
- 🟡 `pmd:TestClassWithoutTestCases` L94
类 'SpellingTest' 可能是测试类,但它不包含任何测试用例。
建议: 为 SpellingTest 补充真正的测试方法,并将 setup/teardown 改为带 @BeforeEach/@AfterEach 的 setUp/tearDown。
- 🟡 `pmd:PublicMemberInNonPublicType` L95
公共成员 'setup' 声明在非公共类型中。
建议: 如果使用 JUnit Jupiter,可去掉 public 修饰;如果保留 JUnit 4,应将测试类声明为 public。
- 🟡 `pmd:PublicMemberInNonPublicType` L97
公共成员 'teardown' 声明在非公共类型中。
建议: 如果使用 JUnit Jupiter,可去掉 public 修饰;如果保留 JUnit 4,应将测试类声明为 public。
- 🟡 `pmd:UseUtilityClass` L102
所有成员都是静态的。考虑添加私有无参构造函数以防止实例化。
建议: 如果 StaticSuiteTest 只是工具类,应添加私有无参构造器;如果它是测试套件,应改用 @RunWith(Suite.class) 与 @SuiteClasses 并删除静态 suite 方法。
- 🟡 `pmd:TestClassWithoutTestCases` L102
类 'StaticSuiteTest' 可能是测试类,但它不包含任何测试用例。
建议: 如果 StaticSuiteTest 是套件类,应添加套件注解并引用真实测试类;否则删除或补充测试方法。
- 🟡 `pmd:JUnit4SuitesShouldUseSuiteAnnotation` L103
JUnit 4 通过注解声明测试套件,而不是通过 suite 方法。
建议: 使用 @RunWith(Suite.class) 和 @SuiteClasses 声明测试套件并删除 suite();若迁移到 JUnit Platform Suite,应使用 @Suite 注解。
- 🟡 `pmd:PublicMemberInNonPublicType` L103
公共成员 'suite' 声明在非公共类型中。
建议: 如果保留 JUnit 4 suite 方法,应将该类声明为 public;如果使用注解套件,类同样应为 public。
- 🟡 `pmd:UseUtilityClass` L109
所有成员都是静态的。考虑添加私有无参构造函数以防止实例化。
建议: 如果 SuiteClassTest 只是工具类,应添加私有无参构造器;如果它是测试套件,应改用注解式套件并删除静态 suite 方法。
- 🟡 `pmd:TestClassWithoutTestCases` L109
类 'SuiteClassTest' 可能是测试类,但它不包含任何测试用例。
建议: 如果 SuiteClassTest 是套件类,应添加套件注解并引用真实测试类;否则删除或补充测试方法。
- 🟡 `pmd:JUnit4SuitesShouldUseSuiteAnnotation` L110
JUnit 4 通过注解声明测试套件,而不是通过 suite 方法。
建议: 使用 @RunWith(Suite.class) 和 @SuiteClasses 声明测试套件并删除 suite();若迁移到 JUnit Platform Suite,应使用 @Suite 注解。
- 🟡 `pmd:PublicMemberInNonPublicType` L110
公共成员 'suite' 声明在非公共类型中。
建议: 如果保留 JUnit 4 suite 方法,应将该类声明为 public;如果使用注解套件,类同样应为 public。
AI 审查 · 7 条建议
- 🔴 [AI] [bug] `assertEquals-argument-order` L43
**assertEquals 参数顺序颠倒,导致失败消息误导**
第 43 行调用 Assert.assertEquals(actual, expected),把 actual 放在了 expected 参数位置。JUnit 的 assertEquals 期望第一个参数是 expected、第二个是 actual;当前写法在断言失败时会输出与实际相反的消息,且语义错误。
建议: 改为 assertEquals("expected should equal actual", expected, actual),并尽量给断言补充消息;若使用 JUnit Jupiter,应为 Assertions.assertEquals(expected, actual)。
- 🔴 [AI] [bug] `suite-returns-null` L104
**StaticSuiteTest.suite() 返回 null,测试套件运行时会触发空指针**
StaticSuiteTest.suite() 直接返回 null。JUnit 执行套件时会尝试遍历返回的 Test 对象,导致 NullPointerException。
建议: 删除 suite() 方法,改用 @RunWith(Suite.class) 和 @SuiteClasses({...});若保留 suite(),请返回非 null 的 TestSuite。
- 🔴 [AI] [bug] `suite-returns-null` L111
**SuiteClassTest.suite() 返回 null,测试套件运行时会触发空指针**
SuiteClassTest.suite() 直接返回 null。JUnit 执行套件时会尝试遍历返回的 Test 对象,导致 NullPointerException。
建议: 删除 suite() 方法,改用 @RunWith(Suite.class) 和 @SuiteClasses({...});若保留 suite(),请返回非 null 的 TestSuite。
- 🟡 [AI] [design] `junit4-assert-usage` L7
**迁移到 JUnit Jupiter 后仍使用 JUnit 4 的 Assert API**
代码中仍导入并使用 org.junit.Assert(如 Assert.assertTrue、Assert.assertEquals、Assert.fail)。在 JUnit Jupiter 下应使用 org.junit.jupiter.api.Assertions,否则断言行为/异常类型与 JUnit 5 不一致,且容易造成依赖混乱。
建议: 将导入改为 import org.junit.jupiter.api.Assertions;,并把所有 Assert. 调用改为 Assertions.(或使用静态导入);同时确认 @Test 导入来自 org.junit.jupiter.api。
- 🟡 [AI] [design] `tautological-assertions` L31
**testTooMany 中的 assertEquals 只比较常量与自身,属于恒真断言**
第 31-35 行的 assertEquals(1, 1)、(2, 2) 等断言只比较常量与自身,即使被测逻辑被删除或出错,测试也会通过。该类断言没有测试价值。
建议: 删除这些无意义断言,改为对被测逻辑设置明确的输入和预期输出;若只是 PMD 演示反例,可在注释中说明。
- 🟡 [AI] [bug] `test-class-visibility` L68
**多个测试类不是 public,若按 JUnit 4 运行将无法发现用例**
MissingAfterTest、MissingBeforeTest、MissingTestAnnotationTest、SpellingTest、StaticSuiteTest、SuiteClassTest 均为包级私有类。当前代码仍混用 JUnit 4 API,若按 JUnit 4 运行,非 public 测试类不会被识别;若按 JUnit Jupiter 运行,又需要先彻底移除 JUnit 4 API。
建议: 统一迁移到 JUnit Jupiter 并将测试类/方法改为包级私有,或保留 JUnit 4 并将所有测试类及测试方法声明为 public。
- 🟡 [AI] [design] `junit-lifecycle-naming` L95
**setup/teardown 拼写不符合 JUnit 生命周期方法命名**
SpellingTest 中 setup() 和 teardown() 缺少大写字母 P/D,JUnit 不会将它们识别为生命周期方法;若意图是初始化/清理,应命名为 setUp/tearDown 并添加 @BeforeEach/@AfterEach
建议: 改为 public void setUp() 并加 @BeforeEachpublic void tearDown() 并加 @AfterEach;同时为类添加真正的 @Test 方法。