I was starting to read about how to write custom Java rules, when I noticed that the library I want to write an assertion for is already being used, at least in the sample library. The library is AssertJ. In the projects I’m involved with, I’ve seen many examples of broken assertions like the following:
assertThat(....getSomeValue().equals(30));
This was obviously written by a developer who didn’t understand “make tests fail before they pass”.
This should be something like this:
assertThat(...getSomeValue()).isEqualTo(30);
The custom rule I want to write would report calls to method “assertThat()” that don’t call predicates on the result. In fact, I wrote a custom xpath rule to do exactly this years ago, but I didn’t fully implement it at the time.
I am proceeding to examine the rules api so I can write this rule myself, but I was wondering, if elements of the SonarQube universe are already using this library, perhaps someone has already written a custom plugin to check for this? I performed a rudimentary search for something like this, but I didn’t find it.
I have proceeded to try to write this plugin, but I’m running into issues.
Modeling it like the example, my test file is the following:
import static org.assertj.core.api.Assertions.*;
public class AssertThatWithNoPredicate {
public Foo foo = new Foo();
@Test
public void assertSomething() throws Exception {
assertThat(foo.getStuff().equals(34));
}
public static class Foo {
private int stuff;
public int getStuff() { return stuff; }
public void setStuff(int aStuff) { this.stuff = stuff; }
}
}
When I got this working with XPath a few years ago, I ended up with the following expression (it’s still in the SonarQube archived forum ):
//classDeclaration[IDENTIFIER[ends-with(@tokenValue, 'Test')]]//expression/primary[@tokenValue='assertThat']
So, that tells me I need to implement “visitExpressionStatement”, and I tried printing out the firstToken text value, and that showed that I did find that expression. However, I don’t know where to go from here. I’m not sure what to do with “primary”, or whether there’s a different wording for this in the Java api.