Difference between @ContextConfiguration and @SpringApplicationConfiguration in Spring Boot Testing?

What is the difference between @ContextConfiguration and @SpringApplicationConfiguration is one of the frequently asked Spring Boot Testing interview questions which is often used to check if the candidate knows about how to unit test Spring boot application. Even though both @ContextConfiguration and @SpringApplicationConfiguration annotations are used along with SpringJUnit4ClassRunner 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 the 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 the application.properties or application.yml file, and other features of the 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 the Spring boot application, including a test for web pages or the 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 the Integration test since Spring 2.5 when it introduced SpringJUnit4ClassRunner and the same goes for testing with the 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 in handy for testing in a more production-like environment. Btw, if you are not familiar with these essential Spring features then I suggest you start with Spring Framework 5: Beginner to Guru course on Udemy, which covers them quite well.

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:

public class BookServiceTest {

private BookService bookService;

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 the BookConfiguration class will be loaded.

The SpringJUnit4ClassRunner is a powerful class that 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 its findByTitle() method, and that bean is automatically injected by SpringJUnit4ClassRunner class so we just left with writing our testBookService() method.

If you are not familiar with auto-wiring You can see Creating Your First Spring Boot Application course on Pluralsight to learn more about autowiring and how Spring boot application starts up.

Difference between @ContextConfiguration and @SpringApplicationConfiguration in Spring Boot Integration Test

Though, you would need a Pluralsight membership to access this course which costs around $29 per month or $299 per year. If you don't have that you can still access this course by taking advantage of their 10-day free trial which allows access to more than 5000+ Pluralsight online courses without any obligation.

Now, coming back to @ContextConfiguration, even though it helps to load application context, it doesn't enable logging or loads additional properties from the application.properties like 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:

public class BookServiceTest {

private BookService bookService;

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. This helps you to write more realistic and practical unit tests.  

If you are new to Spring Boot testing or want to take your Spring Boot testing skills to next level then I highly recommend you to join Testing Spring Boot: Beginner to Guru course by John Thompson on Udemy. This course will help you to master unit testing in Java and Spring boot application with JUnit 5, Mockito, and Spring Boot and help you become a better developer. 

best course to learn Spring Boot Testing for Java programmers

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.

Further Learning
Spring Framework Master Class - Beginner to Expert
Master Microservices with Spring Boot and Spring Cloud
Master Hibernate and JPA with Spring Boot in 100 Steps
Spring Boot Reference Guide
5 Free Spring Framework and Spring Boot Courses
15 Spring Boot Interview Questions for Java Developers
10 Advanced Spring Boot Courses for Java Developers
Top 5 Spring Cloud Annotations for Java Developers
Spring Boot: Efficient Development, Configuration, and Deployment

Thanks for reading this article so far. If you like my explanation of @SpringApplicationConfiguration vs @ContextConfiguration annotation then please share it with your friends and colleagues. If you have any questions or feedback then please drop a note.

P. S. - If you want to learn Spring 5 and Spring Boot 2 from scratch, in a guided, code-focused way then I suggest you take a look at the Learn Spring: The Master Class course by Eugen Paraschive of Baeldung. 

No comments :

Post a Comment