[Java] add extra assert method names to Junit rules

This commit is contained in:
Erwan Moutymbo committed 2024-03-20 12:17:34 +01:00
1 parent 8df40cccf5
commit 42f78b603b
5 files changed
+70 -11

No files matched your search

@@ -13,6 +13,8 @@ import net.sourceforge.pmd.properties.NumericConstraints;
import net.sourceforge.pmd.properties.PropertyDescriptor;
import net.sourceforge.pmd.properties.PropertyFactory;
import java.util.List;
public class JUnitTestContainsTooManyAssertsRule extends AbstractJavaRulechainRule {
private static final PropertyDescriptor<Integer> MAX_ASSERTS =
@@ -22,10 +24,17 @@ public class JUnitTestContainsTooManyAssertsRule extends AbstractJavaRulechainRu
.defaultValue(1)
.build();
private static final PropertyDescriptor<List<String>> EXTRA_ASSERT_METHOD_NAMES =
PropertyFactory.stringListProperty("extraAssertMethodNames")
.desc("Extra valid assertion methods names")
.emptyDefaultValue()
.build();
public JUnitTestContainsTooManyAssertsRule() {
super(ASTMethodDeclaration.class);
definePropertyDescriptor(MAX_ASSERTS);
definePropertyDescriptor(EXTRA_ASSERT_METHOD_NAMES);
}
@Override
@@ -33,7 +42,7 @@ public class JUnitTestContainsTooManyAssertsRule extends AbstractJavaRulechainRu
ASTBlock body = method.getBody();
if (body != null && TestFrameworksUtil.isTestMethod(method)) {
int assertCount = body.descendants(ASTMethodCall.class)
.filter(TestFrameworksUtil::isProbableAssertCall)
.filter(call -> TestFrameworksUtil.isProbableAssertCall(call, getProperty(EXTRA_ASSERT_METHOD_NAMES)))
.count();
if (assertCount > getProperty(MAX_ASSERTS)) {
asCtx(data).addViolation(method);
@@ -9,22 +9,32 @@ import net.sourceforge.pmd.lang.java.ast.ASTMethodCall;
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule;
import net.sourceforge.pmd.lang.java.rule.internal.TestFrameworksUtil;
import net.sourceforge.pmd.properties.PropertyDescriptor;
import net.sourceforge.pmd.properties.PropertyFactory;
import java.util.List;
public class JUnitTestsShouldIncludeAssertRule extends AbstractJavaRulechainRule {
private static final PropertyDescriptor<List<String>> EXTRA_ASSERT_METHOD_NAMES =
PropertyFactory.stringListProperty("extraAssertMethodNames")
.desc("Extra valid assertion methods names")
.emptyDefaultValue()
.build();
public JUnitTestsShouldIncludeAssertRule() {
super(ASTMethodDeclaration.class);
definePropertyDescriptor(EXTRA_ASSERT_METHOD_NAMES);
}
@Override
public Object visit(ASTMethodDeclaration method, Object data) {
ASTBlock body = method.getBody();
if (body != null
&& TestFrameworksUtil.isTestMethod(method)
&& !TestFrameworksUtil.isExpectAnnotated(method)
&& body.descendants(ASTMethodCall.class)
.none(TestFrameworksUtil::isProbableAssertCall)) {
&& TestFrameworksUtil.isTestMethod(method)
&& !TestFrameworksUtil.isExpectAnnotated(method)
&& body.descendants(ASTMethodCall.class)
.none(call -> TestFrameworksUtil.isProbableAssertCall(call, getProperty(EXTRA_ASSERT_METHOD_NAMES)))) {
asCtx(data).addViolation(method);
}
return data;
@@ -6,6 +6,7 @@ package net.sourceforge.pmd.lang.java.rule.internal;
import static net.sourceforge.pmd.util.CollectionUtil.setOf;
import java.util.List;
import java.util.Set;
import net.sourceforge.pmd.lang.java.ast.ASTAnnotation;
@@ -170,14 +171,15 @@ public final class TestFrameworksUtil {
|| TypeTestUtil.isA("junit.framework.Assert", declaring));
}
public static boolean isProbableAssertCall(ASTMethodCall call) {
public static boolean isProbableAssertCall(ASTMethodCall call, List<String> extraAssertMethodNames) {
String name = call.getMethodName();
return name.startsWith("assert") && !isSoftAssert(call)
|| name.startsWith("check")
|| name.startsWith("verify")
|| "fail".equals(name)
|| "failWith".equals(name)
|| isExpectExceptionCall(call);
|| name.startsWith("check")
|| name.startsWith("verify")
|| "fail".equals(name)
|| "failWith".equals(name)
|| extraAssertMethodNames.stream().anyMatch(name::startsWith)
|| isExpectExceptionCall(call);
}
private static boolean isSoftAssert(ASTMethodCall call) {
@@ -914,6 +914,10 @@ Customize the maximum number of assertions used by this Rule to suit your needs.
This rule checks for JUnit4, JUnit5 and TestNG Tests, as well as methods starting with "test".
</description>
<priority>3</priority>
<properties>
<property name="extraAssertMethodNames" type="List[String]"
description="Extra valid assertion methods names"/>
</properties>
<example>
<![CDATA[
public class MyTestCase extends TestCase {
@@ -945,6 +949,10 @@ JUnit tests should include at least one assertion. This makes the tests more ro
with messages provide the developer a clearer idea of what the test does.
</description>
<priority>3</priority>
<properties>
<property name="extraAssertMethodNames" type="List[String]"
description="Extra valid assertion methods names"/>
</properties>
<example>
<![CDATA[
public class Foo extends TestCase {
@@ -0,0 +1,30 @@
package net.sourceforge.pmd.lang.java.rule.internal;
import net.sourceforge.pmd.lang.java.JavaParsingHelper;
import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
import net.sourceforge.pmd.lang.java.ast.ASTMethodCall;
import org.junit.jupiter.api.Test;
import java.util.Collections;
import static net.sourceforge.pmd.util.CollectionUtil.listOf;
import static org.assertj.core.api.Assertions.assertThat;
class TestFrameworksUtilTest {
protected final JavaParsingHelper java = JavaParsingHelper.DEFAULT.withResourceContext(getClass());
@Test
void testIsProbableAssertCallWithoutExtraMethodNames() {
ASTCompilationUnit root = java.parse("class A { { assertThat(1); } }");
ASTMethodCall m = root.descendants(ASTMethodCall.class).toList().get(0);
assertThat(TestFrameworksUtil.isProbableAssertCall(m, Collections.emptyList())).isTrue();
}
@Test
void testIsProbableAssertCallWithExtraMethodNames() {
ASTCompilationUnit root = java.parse("class A { { expectTrue(1); } }");
ASTMethodCall m = root.descendants(ASTMethodCall.class).toList().get(0);
assertThat(TestFrameworksUtil.isProbableAssertCall(m, listOf("expectTrue"))).isTrue();
}
}