Skip to main content

JUnit5 Inner Test Classes Should Be Annotated with @Nested

Medium
best practicestestingstructure

What is it?

This practice is triggered when inner test classes in JUnit5 are not annotated with @Nested. Without this annotation, tests within inner classes will not be executed during the build process.

Why apply it?

If an inner test class is not annotated with @Nested, its tests will not be executed during the build, potentially leading to untested code. On the other hand, static nested test classes should be left without @Nested annotations because they do not share setup and state with the enclosing class.

How to fix it?

Annotate inner test classes with @Nested to ensure they are executed during testing. Do not annotate static nested classes with @Nested to ensure proper test behavior.

Examples

Example 1:

Negative

In this negative example, the inner class is missing the @Nested annotation, meaning its tests will not be executed during the build.

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Nested;

class MyJunit5Test {

@Test
void test() { /* ... */ }

class InnerClassTest { // Noncompliant, missing @Nested annotation
@Test
void testInner() { /* ... */ }
}

@Nested
static class StaticNestedClassTest { // Noncompliant, static class should not use @Nested
@Test
void testStatic() { /* ... */ }
}
}

Example 2:

Positive

In this positive example, the inner class is correctly annotated with @Nested, ensuring its test methods are executed during the build.

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Nested;

class MyJunit5Test {

@Test
void test() { /* ... */ }

@Nested
class InnerClassTest {
@Test
void testInner() { /* ... */ }
}

static class StaticNestedClassTest {
@Test
void testStatic() { /* ... */ }
}
}

Negative

This negative example shows an inner class without @Nested, meaning tests in the inner class won't run, and a static nested class incorrectly using @Nested.

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Nested;

class OuterTest {

@Test
void testOuter() { /* ... */ }

class NonStaticNested { // Noncompliant, missing @Nested annotation
@Test
void testNonStaticNested() { /* ... */ }
}

@Nested
static class FullyStaticNested { // Noncompliant, static nested class erroneously annotated
@Test
void testFullyStatic() { /* ... */ }
}
}

Example 3:

Positive

In the positive example, a @Nested annotation is used correctly on an inner class, and the static nested class is left without @Nested to maintain clear setup separation.

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Nested;

class OuterTest {

@Test
void testOuter() { /* ... */ }

@Nested
class NonStaticNested {
@Test
void testNonStaticNested() { /* ... */ }
}

static class FullyStaticNested {
@Test
void testFullyStatic() { /* ... */ }
}
}