I am going to talk briefly about something that happened to me the other day while writing some unit tests. I discovered a feature from IntelliJ IDEA that was hidden to me and bugged me for a few minutes.
Writing my test
While doing Test Driven Development (TDD), I wrote a test for a method where passing a null
value, it would throw an exception.
In our project we use AssertJ, a good library for assertions which I personally love compared to Hamcrest.
The assertion of the test looked like this:
assertThatThrownBy(() ->
sut.doSomeWork(null)
).isInstanceOf(NullPointerException.class);
I wanted the code to throw a NullPointerException
when a null
value was passed, so I called Objects.requireNonNull(...)
.
Additionally, I thought of adding a @NotNull
annotation to improve its usability (specially if we later decide to use Kotlin 😁).
The method looked like this:
import org.jetbrains.annotations.NotNull;
public String doSomeWork(@NotNull final String str) {
Objects.requireNonNull(str, "Parameter 'str' must not be null");
// ...
}
I run my test suite and the test failed with the following error:
Expecting actual throwable to be an instance of:
java.lang.NullPointerException
but was:
java.lang.IllegalArgumentException: Parameter 'str' must not be null
at java.util.Objects.requireNonNull(Objects.java:228)
...
So I thought:
My bad, I made a mistake. Let us replace the expected exception and problem solved.
Indeed that solved my problem.
Getting confused
When I finished writing my code, I commited my changes and pushed them to my remote GIT repository.
What was my surprise when my Continuous Integration (CI) pipeline failed with the next message:
Expecting actual throwable to be an instance of:
java.lang.IllegalArgumentException
but was:
java.lang.NullPointerException: Parameter 'str' must not be null
at java.util.Objects.requireNonNull(Objects.java:228)
...
This was me puzzled. What is going on!?
Following, I did something I admit I should have done in the beginning, I went to check the implementation of Objects.requireNonNull(...)
.
It looks like this in Java 8:
public static <T> T requireNonNull(T var0, String var1) {
if (var0 == null) {
throw new NullPointerException(var1);
} else {
return var0;
}
}
So I actually wrote the test right in the first place! Why is then IntelliJ IDEA failing with a different error?
Finding out the issue
I did some research and it turns out this is not a bug, it is a feature from IntelliJ IDEA 🤦♂️.
Apparently IntelliJ IDEA adds some runtime assertions for @NotNull
annotated methods and parameters.
Fortunately, this can be disabled in the Settings (or Preferences, depending on your OS) of IntelliJ IDEA.
Go to Build, Execution, Deployment > Compiler
.
We must disable the option Add runtime assertions for notnull-annotated methods and parameters
:
After disabling that option, my test had the same result both in my machine and in the CI pipeline. Nice!
Note: If that did not work straight away, you may need to invalidate cache and restart your IDE and/or rebuild your project.
If you were puzzled like me and were looking for a solution or just to throw some light into the issue, I hope this was helpful!
Thanks for reading!
If you found this article interesting, share it!