Difference between @ContextConfiguration and @SpringApplicationConfiguration in Spring Boot Integration Test
Even though both @ContextConfiguration
and @SpringApplicationConfiguration
annotations are used along withSpringJUnit4ClassRunner
to specify how to load the Spring application context, there is a subtle difference between them. Although @ContextConfiguration
does a great job in loading application context it doesn’t take full advantage of Spring Boot features. Spring Boot applications are ultimately loaded by either SpringApplication ( in case of the JAR) or SpringBootServletInitializer
. This class not only loads the application context but also enables logging and loading of external properties specified in application.properties or application.yml file, and other features of Spring Boot framework, which is not loaded or enabled by the @ContextConfiguration
annotation.
In short, it’s better to use the @SpringApplicatoinConfiguration
annotations rather than @ContextConfiguration
for writing an integration test for Spring boot application, including a test for web pages or front end of the application.
Now that you know the essential difference between @ContextConfiguration
and @SpringApplicationConfiguration
annotations while writing Spring boot tests, let’s understand that in a little bit more details with some code samples.
Spring Framework has excellent support for writing Integration test since Spring 2.5 when it introduced SpringJUnit4ClassRunner
and the same goes for testing with Spring Boot application. During the Integration test, you also need to load beans and wire them up with dependency.
Of course, you can do that manually but it’s better if Spring handles them for you, which it does. It also offers out-of-the-box features such as component scanning, autowiring, declaration transaction management, security, and caching, which comes handy for testing in a more production-like environment.
Spring Boot -@ContextConfiguration example
Here is a simple Spring integration test with SpringJUnit4ClassRunner
and@ContextConfiguration
annotation, one of the essential Spring boot annotations for loading application context:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 | @RunWith (SpringJUnit4ClassRunner. class ) @ContextConfiguration (classes=BookConfiguration. class ) public class BookServiceTest { @Autowired private BookService bookService; @Test public void testBookService() { Book aBook = bookService.findByTitle( "Spring Boot in Action" ); assertEquals( "Craig Walls" , aBook.getAuthor()); assertEquals( 40 , aBook.getPrice()); } } |
As you can see, the BookServiceTest class is annotated with both the@RunWith
JUnit annotation and @ContextConfiguration annotations.
The @RunWith
annotation is required to enable Spring integration testing and that’s why we have passed the SpringJUnit4ClassRunnner
class to it, while @ContextConfiguration
annotation specifies how to load application context.
In this example, the Spring application context defined in theBookConfiguration
class will be loaded.
The SpringJUnit4ClassRunner
is a powerful class which not only loads the application context but also autowire beans into the test as well.
For example, in this test class, we needed a BookService to test itsfindByTitle()
method and that bean is automatically injected by SpringJUnit4ClassRunner
class so we just left with writing our
testBookService() method.
Now, coming back to @ContextConfiguration
, even though it helps to load application context, it doesn’t enable logging or loads additional properties from application.properties e.g. server.port property which is required to change the port of embedded tomcat server in spring boot application.
To solve that problem, you can use @SpringApplicaitonCongifguation
annotation in place of @ContextConfiguration
as shown below:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 | @RunWith (SpringJUnit4ClassRunner. class ) @SpringApplicaitonCongifguation (classes=BookConfiguration. class ) public class BookServiceTest { @Autowired private BookService bookService; @Test public void testBookService() { Book aBook = bookService.findByTitle( "Cloud Native Java" ); assertEquals( "Josh Long" , aBook.getAuthor()); assertEquals( 40 , aBook.getPrice()); } } |
This one will behave the same as the previous example but @SpringApplicationConfiguration
will also enable Spring boot logging and load additional properties defined in application.properties or application.yml file.
That’s all about the difference between @ContextConfiguration
and @SpringApplicationConfiguration
annotation in Spring Boot. Even though both used along with SpringJUnit4ClassRunner
and help with the loading application context, later is more useful because it also enables logging and other spring Boot features.
It’s always better to use @SpringApplicationConfiguration
while writing an integration test for the Spring Boot application to get your test as close to production as possible.
Thanks for reading this article so far. If you like my explanation of@SpringApplicationConfiguration
vs @ContextConfiguration
annotation then please share with your friends and colleagues. If you have any questions or feedback then please drop a note.
Published on Java Code Geeks with permission by Javin Paul, partner at our JCG program. See the original article here: Difference between @ContextConfiguration and @SpringApplicationConfiguration in Spring Boot Integration Test Opinions expressed by Java Code Geeks contributors are their own. |
I think it’s better to show the differences using sample code.