1 min read

How IntelliJ IDEA played a dirty trick on me

It was not a bug, it was a feature

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)
    ...
Confused man screaming What

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:

Screenshot of settings screen

This is the option to disable.

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!


Follow my journey

Get the latest updates in your inbox 📨

    No spam. Unsubscribe as your heart desires.