3

I'm trying to implement integration testing in my app and have test class like that:

@ExtendWith(value={MyDockerExtension.class})
@ExtendWith(value={SpringExtension.class})
@WebAppConfiguration
@ContextConfiguration(classes={...})
@TestInstance(TestInstance.LifeCycle.PER_CLASS)
public class TestClass{ ... }

Is there any way to make MyDockerExtension execute some code, before whole SpringExtension start working and generate whole Context with Configurationc classes?

I've heard that order in which we declare extensions is the key, but sadly MyDockerExtension that implements BeforeAllCallback, AfterAllCallback executes right before test method and after whole context is loaded. In that situation it's to late to start containers with docker, becuase since whole context is loaded my app already tried to connect to the container.

Guy Coder
  • 24,501
  • 8
  • 71
  • 136
ogarogar
  • 323
  • 2
  • 14

1 Answers1

4

At first I was skeptical about the order being fixed but you're correct:

Extensions registered declaratively via @ExtendWith will be executed in the order in which they are declared in the source code.

Regarding the MyDockerExtension, you may want to look at the extension point TestInstancePostProcessor, which is called before @BeforeAll. SpringExtension implements it and I guess it's there where it sets up the application context. If you also implement it, you should be able to act before it does.

Nicolai Parlog
  • 47,972
  • 24
  • 125
  • 255
  • 1
    As the author of the `SpringExtension`, I can confirm that @Nicolai is correct. The `ApplicationContext` is loaded first (typically) when performing dependency injection which is triggered via the `TestInstancePostProcessor` extension API. Since you're using `PER_CLASS` test instance lifecycle semantics, the `BeforeAllCallback` extension API is invoked _after_ the `TestInstancePostProcessor`. If you were using `PER_METHOD` lifecycle, it would be the other way around. – Sam Brannen Jul 28 '18 at 09:26