diff --git a/its/autoscan/src/test/resources/autoscan/diffs/diff_S2699.json b/its/autoscan/src/test/resources/autoscan/diffs/diff_S2699.json index a1771da2a20..d361a3c2311 100644 --- a/its/autoscan/src/test/resources/autoscan/diffs/diff_S2699.json +++ b/its/autoscan/src/test/resources/autoscan/diffs/diff_S2699.json @@ -1,6 +1,6 @@ { "ruleKey": "S2699", "hasTruePositives": true, - "falseNegatives": 147, + "falseNegatives": 151, "falsePositives": 1 -} \ No newline at end of file +} diff --git a/java-checks-test-sources/default/pom.xml b/java-checks-test-sources/default/pom.xml index 78cf590ec39..e3940c97351 100644 --- a/java-checks-test-sources/default/pom.xml +++ b/java-checks-test-sources/default/pom.xml @@ -296,6 +296,12 @@ 5.3.12 provided + + org.springframework.boot + spring-boot-starter-test + 3.2.4 + provided + org.springframework spring-jdbc diff --git a/java-checks-test-sources/default/src/test/java/checks/tests/AssertionsInTestsCheck/SpringBootSanityJ4Test.java b/java-checks-test-sources/default/src/test/java/checks/tests/AssertionsInTestsCheck/SpringBootSanityJ4Test.java new file mode 100644 index 00000000000..f7811256cb5 --- /dev/null +++ b/java-checks-test-sources/default/src/test/java/checks/tests/AssertionsInTestsCheck/SpringBootSanityJ4Test.java @@ -0,0 +1,31 @@ +package checks.tests.AssertionsInTestsCheck; + +import org.junit.Test; +import org.junit.experimental.runners.Enclosed; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; + +@RunWith(Enclosed.class) +@SpringBootTest +public class SpringBootSanityJ4Test { + + @Test + public void contextLoads() { // Compliant, no assertions needed for this spring sanity test + } + + @Test + public void anotherTest(){ // Noncompliant, no assertions + + } + + public static class NotASpringBootSanityJ4Test { + + @Test + public void contextLoads() { // Noncompliant + } + + } + +} + + diff --git a/java-checks-test-sources/default/src/test/java/checks/tests/AssertionsInTestsCheck/SpringBootSanityTestSample.java b/java-checks-test-sources/default/src/test/java/checks/tests/AssertionsInTestsCheck/SpringBootSanityTestSample.java new file mode 100644 index 00000000000..62e3cb9a863 --- /dev/null +++ b/java-checks-test-sources/default/src/test/java/checks/tests/AssertionsInTestsCheck/SpringBootSanityTestSample.java @@ -0,0 +1,26 @@ +package checks.tests.AssertionsInTestsCheck; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class SpringBootSanityTest { + + @Test + void contextLoads() { // Compliant, no assertions needed for this spring sanity test + } + + @Test + void anotherTest(){ // Noncompliant, no assertions + + } + +} + +class NotASpringBootSanityTest { + + @Test + void contextLoads() { // Noncompliant + } + +} diff --git a/java-checks/src/main/java/org/sonar/java/checks/tests/AssertionsInTestsCheck.java b/java-checks/src/main/java/org/sonar/java/checks/tests/AssertionsInTestsCheck.java index abcd84efff7..b45a37bca23 100644 --- a/java-checks/src/main/java/org/sonar/java/checks/tests/AssertionsInTestsCheck.java +++ b/java-checks/src/main/java/org/sonar/java/checks/tests/AssertionsInTestsCheck.java @@ -36,6 +36,7 @@ import org.sonar.plugins.java.api.semantic.Symbol; import org.sonar.plugins.java.api.semantic.SymbolMetadata; import org.sonar.plugins.java.api.tree.BaseTreeVisitor; +import org.sonar.plugins.java.api.tree.ClassTree; import org.sonar.plugins.java.api.tree.MethodTree; import org.sonar.plugins.java.api.tree.Modifier; import org.sonar.plugins.java.api.tree.Tree; @@ -77,11 +78,19 @@ public void visitMethod(MethodTree methodTree) { return; } - if (isUnitTest(methodTree) && !expectAssertion(methodTree) && !isLocalMethodWithAssertion(methodTree.symbol())) { + if (isUnitTest(methodTree) && !isSpringBootSanityTest(methodTree) && !expectAssertion(methodTree) && !isLocalMethodWithAssertion(methodTree.symbol())) { context.reportIssue(this, methodTree.simpleName(), "Add at least one assertion to this test case."); } } + private static boolean isSpringBootSanityTest(MethodTree methodTree){ + if("contextLoads".equals(methodTree.simpleName().name())){ + ClassTree classTree = (ClassTree) methodTree.parent(); + return classTree.symbol().metadata().isAnnotatedWith("org.springframework.boot.test.context.SpringBootTest"); + } + return false; + } + private boolean isLocalMethodWithAssertion(Symbol symbol) { if (!assertionInMethod.containsKey(symbol)) { assertionInMethod.put(symbol, false); diff --git a/java-checks/src/test/java/org/sonar/java/checks/tests/AssertionsInTestsCheckTest.java b/java-checks/src/test/java/org/sonar/java/checks/tests/AssertionsInTestsCheckTest.java index 5e7b36a680a..f6a306148b6 100644 --- a/java-checks/src/test/java/org/sonar/java/checks/tests/AssertionsInTestsCheckTest.java +++ b/java-checks/src/test/java/org/sonar/java/checks/tests/AssertionsInTestsCheckTest.java @@ -107,4 +107,17 @@ void testWithEmptyCustomAssertionMethods() { assertThat(logTester.logs(Level.WARN)) .doesNotContain("Unable to create a corresponding matcher for custom assertion method, please check the format of the following symbol: ''"); } + + @Test + void testSpringBootSanity(){ + CheckVerifier.newVerifier() + .onFile(testCodeSourcesPath("checks/tests/AssertionsInTestsCheck/SpringBootSanityTestSample.java")) + .withCheck(check) + .verifyIssues(); + + CheckVerifier.newVerifier() + .onFile(testCodeSourcesPath("checks/tests/AssertionsInTestsCheck/SpringBootSanityJ4Test.java")) + .withCheck(check) + .verifyIssues(); + } }