How can I initialize a Spring applicationContext j

2019-04-16 15:58发布

问题:

I have a set of tests based which need a spring context.

For fast test execution I want to make sure that the Spring context is initialized just once, then all the tests should be run against this context, then it should shut down.

I already tried the following approaches:

  1. Use @RunWith(SpringJUnit4ClassRunner.class) and @ContextConfiguration(MyAnnotatedConfig.class) to initialize the spring context
  2. Use a @RunWith(SpringJUnit4ClassRunner.class) and @TestExecutionListeners({MyTestExecutionListener.class}) with a handwritten test execution listener that initializes the spring context and injects it into the concrete test classes
  3. Use a @BeforeClass listener in a base class and a static field to store the spring context, and a @AfterClass for shutdown

With all three approaches, the spring context seems to be initialized more than once, which takes a lot of time. It seems that JUnit unloads classes while running tests, so that the content of static fields is sometimes lost.

Is there a way to make sure the spring context is initialized only once?

回答1:

For fast test execution I want to make sure that the Spring context is initialized just once, then all the tests should be run against this context, then it should shut down.

I hate to ask the obvious, but...

Have you read the Testing chapter of the Spring Reference Manual?

Specifically, these sections explain what's going on:

  • Context management and caching
  • Context caching

Soooo, the TestContext framework certainly supports caching across tests within a test suite, and I should know, because I wrote it. ;)

Now as for why caching is not working for you, I can only assume that you have configured your build framework to fork for each test (or that you are running tests individually and manually within your IDE). Here's an excerpt from the last link above that might help you out:

Test suites and forked processes

The Spring TestContext framework stores application contexts in a static cache. This means that the context is literally stored in a static variable. In other words, if tests execute in separate processes the static cache will be cleared between each test execution, and this will effectively disable the caching mechanism.

To benefit from the caching mechanism, all tests must run within the same process or test suite. This can be achieved by executing all tests as a group within an IDE. Similarly, when executing tests with a build framework such as Ant, Maven, or Gradle it is important to make sure that the build framework does not fork between tests. For example, if the forkMode for the Maven Surefire plug-in is set to always or pertest, the TestContext framework will not be able to cache application contexts between test classes and the build process will run significantly slower as a result.

If you still experience issues after taking the above into consideration, please consider submitting a project that demonstrates your problem.

Cheers,

Sam