0

I use spring 5 + junit 5. And I have two classes - BarIT and FooIT.

@ExtendWith({SpringExtension.class})
@ContextConfiguration(classes = ModuleContextConfig.class)
public class FooIT {

    @Test
    public void foo() {
        System.out.println("Foo");
    }
}

@ExtendWith({SpringExtension.class})
@ContextConfiguration(classes = ModuleContextConfig.class)
public class BarIT {

    @Test
    public void bar() {
        System.out.println("Bar");
    }
}

This is my suite:

@RunWith(JUnitPlatform.class)
@ExtendWith({SpringExtension.class})
@SelectClasses({
    FooIT.class,
    BarIT.class
})
@IncludeClassNamePatterns(".*IT$")
public class SuiteIT {

}

I want to get event when tests in two classes have been executed, I mean event after FooIT.foo() and BarIT.bar(), however, I can't do that. I hoped to get ContextClosedEvent but it is not fired:

@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
public class ApplicationListenerBean implements ApplicationListener {

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        System.out.println("Event:" + event.toString());
    }
}

And this is the output:

Event:org.springframework.context.event.ContextRefreshedEvent..
Event:org.springframework.test.context.event.PrepareTestInstanceEvent..
Event:org.springframework.test.context.event.BeforeTestMethodEvent..
Event:org.springframework.test.context.event.BeforeTestExecutionEvent..
Foo
Event:org.springframework.test.context.event.AfterTestExecutionEvent...
Event:org.springframework.test.context.event.AfterTestMethodEvent...
Event:org.springframework.test.context.event.AfterTestClassEvent...
Event:org.springframework.test.context.event.BeforeTestClassEvent...
Event:org.springframework.test.context.event.PrepareTestInstanceEvent...
Event:org.springframework.test.context.event.BeforeTestMethodEvent...
Event:org.springframework.test.context.event.BeforeTestExecutionEvent...
Bar
Event:org.springframework.test.context.event.AfterTestExecutionEvent...
Event:org.springframework.test.context.event.AfterTestMethodEvent...
Event:org.springframework.test.context.event.AfterTestClassEvent..

Could anyone say how to do it, if it is possible.

Pavel_K
  • 10,748
  • 13
  • 73
  • 186
  • Perhaps [this answer](https://stackoverflow.com/a/64070019/1092818) will help? – crizzis Oct 31 '20 at 23:29
  • @crizzis Thank you for your comment. I know, that there junit extensions, but I try to find a way to do it only using spring and only with one extension - `@ExtendWith({SpringExtension.class})`. – Pavel_K Nov 01 '20 at 06:38
  • In such case, you could try using a custom [`TestExecutionListener`](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/test/context/TestExecutionListener.html) and keeping track which test classes have finished executing in `afterTestClass()`. you can override the default listener chain using `@TestExecutionListeners`, just make sure to include all the default listeners your tests need. It will take similar effort to a JUnit extension, though – crizzis Nov 01 '20 at 10:05
  • @crizzis Yes, I thought about it. But to get the point after all classes I can only if I know how many tests junit has (after that I only count tests and find the remainder). But I didn't find a way to get test count from junit.... – Pavel_K Nov 01 '20 at 10:28
  • Not sure I follow. The suite has a fixed list of included test classes. Just hardcode the same list in the listener, and tick off the classes from the list when `afterTestClass()` gets called. Once the list is empty, you'll know that the last test from the suite finished executing. With some extra effort, you could even read the list off `@SelectClasses`, since it has runtime retention – crizzis Nov 01 '20 at 10:33
  • @crizzis This doesn't work, if you have `@Ignore` `@Tag` etc. Number of test can be taken only from junit. – Pavel_K Nov 01 '20 at 10:40
  • ...and that's precisely the reason why a JUnit extension is better suited for the job. With the constraint that only `SpringExtension` can be used, only a solution with limited usability can be reached. Note also that the original approach with `ContextClosedEvent` wouldn't work with `@DirtiesContext`, for example, because closing the context is not tantamount to having run all tests – crizzis Nov 01 '20 at 10:47

0 Answers0