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();
+ }
}