Hello everyone,
I was able to declare in the tests that I expect two/more issues on the same line.
This worked very well until I have implemented another test with the same requirement (multiple issues on the same line).
Then the previous test is failing because somehow the order of the // Noncompliant
tags is important and random.
All of them are being added in a collection and when an issue is detected only the last one is verified. This will fail if the order is changed and maybe the verified string is there but on a different position.
Steps to reproduce:
Clone repo: https://github.com/SonarSource/sonar-custom-rules-examples/tree/master/java-custom-rules
Extend AvoidAnnotationRule class to report two issue in the same place:
@Override
public void visitMethod(MethodTree tree) {
List<AnnotationTree> annotations = tree.modifiers().annotations();
for (AnnotationTree annotationTree : annotations) {
if (annotationTree.annotationType().is(Tree.Kind.IDENTIFIER)) {
IdentifierTree idf = (IdentifierTree) annotationTree.annotationType();
System.out.println(idf.name());
if (idf.name().equals(name)) {
context.reportIssue(this, idf, String.format("Avoid using annotation @%s", name));
context.reportIssue(this, idf, String.format("Exception 2 @%s", name));
}
}
}
My test class:
package org.sonar.samples.java.checks;
import org.junit.Test;
import org.sonar.java.checks.verifier.JavaCheckVerifier;
public class AvoidAnnotationCheckTest {
@Test
public void detected() {
// Use an instance of the check under test to raise the issue.
AvoidAnnotationRule check = new AvoidAnnotationRule();
// define the forbidden annotation name
check.name = "Zuper";
JavaCheckVerifier.verify("src/test/files/AvoidAnnotationCheck.java", check);
}
}
File under test:
/**
*This file is the sample code against we run our unit test.
*It is placed src/test/files in order to not be part of the maven compilation.
**/
class AvoidAnnotationCheck {
int aField;
@MyAnnotation
public void aMethod() {
}
// Noncompliant@+2 {{Exception 2 @Zuper}}
// Noncompliant@+1 {{Avoid using annotation @Zuper}}
@Zuper
public void aMethod() {
}
// Noncompliant@+2 {{Avoid using annotation @Zuper}}
// Noncompliant@+1 {{Exception 2 @Zuper}}
@Zuper
public void anotherMethod() {
}
}
Now this will work but If you duplicate the test I will have errors:
org.junit.ComparisonFailure: [Line: 16 attribute mismatch for MESSAGE: {MESSAGE=Avoid using annotation @Zuper}] expected:<"[Avoid using annotation] @Zuper"> but was:<"[Exception 2] @Zuper">
Basically, the order is different and I need to switch the position of the // Noncompliant
comments
I have checked the code of the sonar verify class and I found something which can be the source of the problem:
private static void validateIssue(Multimap<Integer, Map<IssueAttribute, String>> expected, List<Integer> unexpectedLines, AnalyzerMessage issue, @Nullable RemediationFunction remediationFunction) {
int line = issue.getLine();
if (expected.containsKey(line)) {
Map<IssueAttribute, String> attrs = Iterables.getLast(expected.get(line));
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ here we only take the last result
assertEquals(line, issue.getMessage(), attrs, IssueAttribute.MESSAGE);
Is there something wrong with my tests? Is there another way to do it? I also tried with the new verifier and I have the same problem
Thank you very much for your time, I will appreciate any help