JUnit Assertions should not be used in production code

JUnit assertions are intended to be used in test code, but not in production code.

  • Using JUnit assertions outside of test scope may be confusing.
  • Build tools such as Maven might provide JUnit only in test scope, which means JUnit will be missing in the class path, so any invocation of a JUnit assertion in production code (regardless of its outcome) might throw a ClassNotFoundException.

Noncompliant Code Example

package com.myfoo;

import static org.junit.jupiter.api.Assertions.*;

class Foo {
  // ...
  void doSomething() {
   Integer result = getResult();
   assertNotNull(result);    // Noncompliant -- JUnit method in production code
   assertTrue(result > 0);   // Noncompliant
   assertEquals(42, result); // Noncompliant
  }
}

Compliant Code Examples

package com.myfoo;

import java.util.Objects;
import org.apache.commons.lang3.Validate;

// ...
class Foo {
  // ...
  void doSomething() {
   Integer result = getResult();
   Objects.requireNonNull(result);  // Compliant
   Validate.validState(result > 0); // Compliant
   assert result.equals(42);        // Compliant -- built-in assert
  }
}
package com.myfoo;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

import org.junit.jupiter.api.Test;

class FooTest {
  // ...
  @Test
  void testSomething() {
   Integer result = foo.getResult();
   assertNotNull(result);      // Compliant -- in test scope
   assertTrue(result > 0);     // Compliant -- in test scope
   assertEquals(42, result);   // Compliant -- in test scope
  }
}
  • type : Bug

Note: this rule could be extended to cover other unit testing frameworks and libraries.

Hello @bduderstadt,

I like the idea, we did not specify the rule further yet, but we plan to add a new set of rules targeting tests for Java in the future, we will definitely come back to your idea when we will start this effort.

I’m also wondering if this could be generalized to any assertion…

Anyway, thanks for the proposition!

Best,
Quentin

1 Like

Hi @Quentin,

I’m also wondering if this could be generalized to any assertion…

JUnit assertions are supposed to be used only in test scope, and this may be true as well for other test frameworks or assertion libraries for languages other than Java.
There is also already a rule that advises against using assert statements for validating parameters
of public methods: https://rules.sonarsource.com/java/RSPEC-4274

However, I don’t think that assertions should be banned from production code in general. Assertions are helpful in documenting the programmer’s assumptions about the inner state of the application.
An assertion that fails indicates a bug, because an assumption was false. The bug remains if you simply remove the assertion.

It is a good practice to review asserts before going live, and replacing them by proper checks where appropriate. I think there may be cases where it is not necessary to remove all assertions.

1 Like

For the record, we started specifying a rule based on your proposition: RSPEC-5960.

It is still subject to change until it reaches production though, but the example you provided will definitely be supported.

Thanks again for your participation.

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.