1

I have a test class which in the future will test different conditions for tests and I'd like to make it more structured and fit only into one file. I found this solution but it doesn't suit me because I can't combine a SpringRunner.class and Enclosed.class to fit it into one @RunWith. I can't use Nitor Creation's Nested Runner - it brings the same problem.

I use Spring 5 and Junit 4.12. Well... my question is, how to combine my tests inside a few inner/nested classes with one root class?

UPD: one remark - I can't make an upgrade to Junit 5.

Woods
  • 119
  • 1
  • 12

1 Answers1

3

JUnit 4

If you need to stick with JUnit 4, you can use a third-party plugin to provide support. See the junit-hierarchicalcontextrunner provided by bechte on GitHub.

Add the dependency to your project, and use the HeirachalContextRunner like so:

@RunWith(HierarchicalContextRunner.class)
public class NestedTest {

    @ClassRule
    public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();

    @Rule
    public final SpringMethodRule  springMethodRule = new SpringMethodRule();

    @Before
    public void setup() {
        // General test-suite setup
    }

    public class NestedClass {

        @Test
        public void testSomething() {
            // Test
        }

        public class AnotherNestedClass {

            @Test
            public void testSomethingElse() {
                // Test
            }
        }
    }
}

Note that we don't need to specify Spring's runner here. Instead, we use the rules to apply the Spring test framework, available as of Spring 4.2.

JUnit 5

Arguably a more future-proof solution would be to upgrade to JUnit 5. Then you can construct test cases straight out of the box, with the @Nested annotation. See below:

@SpringBootTest
@ExtendWith(SpringExtension.class)
class MyNestedTest {

    @BeforeAll
    void setup() {
        // General test-suite setup
    }

    @Nested
    @DisplayName("parentTestSuite")
    class NestedClass {

        @Test
        void testSomething() {
            // Test
        }

        @Nested
        @DisplayName("childTestSuite")
        class AnotherNestedClass {

            @Test
            void testSomethingElse() {
                // Test
            }

        }
    }
}

Note that @RunWith has been replaced with @ExtendWith in JUnit 5. If you choose to migrate to JUnit 5, you may find it useful to read Baeldung's guide on JUnit 5 migration.

Daniel Scarfe
  • 199
  • 1
  • 8
  • 1
    I can't make an upgrade to Junit 5 and I should have labeled it. I like this solution, I will keep it in mind. Thank you) – Woods Jul 29 '19 at 10:06
  • @Woods understood - see my recent edit for a JUnit 4 compatible solution using a third-party library. – Daniel Scarfe Jul 29 '19 at 10:19
  • @Woods the important thing to note is that you can use another runner if you replace your `SpringRunner` with Spring's JUnit rules (introduced in version `4.2`). – Daniel Scarfe Jul 29 '19 at 10:28
  • @ExtendWith(SpringExtension.class) is not required since it is included already in @SpringBootTest – Palo Jun 08 '22 at 12:08