In this blog post, you will learn the difference between @SpringBootTest and @WebMvcTest annotations.
The main difference between the @SpringBootTest
and @WebMvcTest
annotations lies in the application context that they create. The @SpringBootTest
annotation starts the full application context, which includes all the beans required for the application to function. On the other hand, the @WebMvcTest
annotation creates an application context with a limited number of beans, specifically those related to the Web Layer.
The @SpringBootTest
annotation is typically used for integration tests, where you need to test the whole application from a top-down perspective. In contrast, the @WebMvcTest
annotation is more focused and is used to test the Web MVC Layer, including controllers, filters, and other components related to handling HTTP requests and responses. By limiting the number of beans in the application context, @WebMvcTest
can help you isolate the Web Layer and make tests faster and more focused.
@SpringBootTest Annotation
The @SpringBootTest
annotation makes the Spring Framework scan all three layers of your application: the Web layer, Service layer, and Data layer. By default, Spring Framework scans your application classes from the root package, and any classes annotated with annotations such as @Component
, @Repository
, @Service
, and @Controller
will be converted into beans and added to the application context.
What is it used for?
The @SpringBootTest
annotation is typically used to test the whole application from a top-down perspective. Integration tests using @SpringBootTest
allow you to test the interaction between the different layers of your application, including the controllers, services, repositories, and other beans.
How does it work?
When you use the @SpringBootTest
annotation, Spring Framework creates a complete application context that includes all the beans required for your application to function. This includes any custom beans defined in your application, as well as any beans created by Spring itself.
Once the application context is created, you can use it to test the interaction between different layers of your application. For example, you can use @SpringBootTest
to test your controllers and ensure they are properly interacting with your services and repositories. This allows you to catch integration issues early and ensure that your application is functioning as expected.
You can customize the behaviour of @SpringBootTest
using various attributes, including the webEnvironment
attribute. The webEnvironment
attribute allows you to specify the type of environment to use when running the tests. This can be particularly useful if you need to test your application in a specific context, such as when you are testing interactions with external services or need to ensure that your application is running correctly in a specific environment.
The webEnvironment
attribute can take the following values:
WebEnvironment.MOCK
: This is the default value and is used to run the tests in a mock web environment. This means that the tests will not start a server or bind to a network port. Instead, the tests will use a mock implementation of the web environment to simulate HTTP requests and responses.WebEnvironment.RANDOM_PORT
: This option starts the application in a real web environment and binds to a random network port. This is useful when you need to test your application in a real environment, but don’t want to use a specific port number.WebEnvironment.DEFINED_PORT
: This option starts the application in a real web environment and binds to a specific port number. This is useful when you need to test your application in a real environment and need to use a specific port number.WebEnvironment.NONE
: This option starts the application context without any web environment. This is useful when you need to test your application context without any web components.
For further explanations, you can find an example of the @SpringBootTest
annotation in action by following this link @SpringBootTest Annotation Example.
@WebMvcTest Annotation
The @WebMvcTest
annotation is a testing annotation in the Spring Framework that is used to test the web layer of an application. It is a lightweight alternative to the @SpringBootTest
annotation and is used for testing web-related components.
What is it used for?
The @WebMvcTest
annotation is typically used to test only the web layer of your application. It creates a limited application context that includes only the beans related to the web layer. This allows you to focus on testing the controllers, views, and related components of your application without having to load the entire application context.
How does it work?
When you use the @WebMvcTest
annotation, Spring Framework creates a limited application context that includes only the beans related to the web layer. This includes the controllers, views, and related components required to handle incoming HTTP requests.
You can customize the behavior of @WebMvcTest
using various attributes, including the value
attribute. The value
attribute allows you to specify which controllers to test. You can specify one or more controllers to test by passing them as arguments to the value
attribute.
Suppose you have two controllers in your application, UserController
and ProductController
, and you only want to test the UserController
. You can specify the UserController
to be tested using the value
attribute like this:
@WebMvcTest(UserController.class) public class UserControllerTests { // tests for UserController go here }
In this example, the @WebMvcTest
annotation is used to create a limited application context that includes only the beans related to the UserController
. This allows you to focus on testing the behavior of the UserController
without having to load the entire application context.
Once the application context is created, you can use it to test the behaviour of your controllers and views. For example, you can use @WebMvcTest
to test that your controllers are properly handling incoming HTTP requests and generating the correct HTTP responses. This allows you to ensure that the web layer of your application is functioning as expected without having to load the entire application context.
Note: Keep in mind that if your controller class has a dependency on a @Service
or @Repository
object, you’ll need to use the @MockBean
annotation to mock this dependency.
@SpringBootTest vs @WebMvcTest
The @SpringBootTest
and @WebMvcTest
annotations are both used for testing Spring applications, but they serve different purposes. Here are some key differences between the two annotations:
Scope of testing
@SpringBootTest
is used to test the entire application context of your Spring application, including the web layer, service layer, and data access layer.@WebMvcTest
, on the other hand, is used to test only the web layer of your application. It creates a limited application context that includes only the beans related to the web layer, such as controllers, views, and exception handlers. This approach is also known as “slicing” the application context.
Loading of the application context
- With
@SpringBootTest
, the entire application context is loaded, making all the beans available for testing. - With
@WebMvcTest
, only a limited application context is loaded, containing only the beans required to test the web layer.
Dependencies
@SpringBootTest
does not require any additional annotations to mock dependencies.- With
@WebMvcTest
, if your controller has a dependency on a service or repository bean, you’ll need to use the@MockBean
annotation to mock that dependency.
Use cases
@SpringBootTest
is ideal for integration testing, where you need to test the interaction between different components of your application.@WebMvcTest
is best suited for testing only the web layer of your application, allowing you to focus specifically on the behavior of your controllers, views, and related components.
By understanding the differences between @SpringBootTest
and @WebMvcTest
, you can choose the appropriate annotation for your specific testing needs.
When to use @SpringBootTest and @WebMvcTest annotations?
The choice between @SpringBootTest
and @WebMvcTest
will depend on the specific use case of your tests.
Use @SpringBootTest when:
- You want to test the entire application context, including all the layers of the application (web, service, and data access).
- You want to test the interaction between different components of the application, such as the web layer and the service layer.
- You want to test the application in a more realistic environment, with all the beans loaded and running.
Use @WebMvcTest when:
- You want to test only the web layer of the application.
- You want to test a specific slice of the application, such as a controller and its related components (views, exception handlers, etc.).
- You want to test the behaviour of the web layer in isolation from the rest of the application.
- You want to test the web layer with a limited number of beans for faster and more focused testing.
It’s important to note that @WebMvcTest
should be used in conjunction with other testing annotations, such as @MockBean
, to ensure that all dependencies are properly mocked. Additionally, both annotations can be used in combination with other Spring testing features, such as @DataJpaTest
for testing the data access layer. Ultimately, the choice of which annotation to use will depend on the specific needs of your application and tests.
Conclusion
In conclusion, understanding the difference between @SpringBootTest
and @WebMvcTest
annotations is crucial when it comes to testing your Spring Boot applications. While both annotations have their own specific use cases, they are designed to work together to provide a comprehensive testing environment.
@SpringBootTest
is used to test the entire application context and its interaction between different components, while @WebMvcTest
is used to test the web layer of the application in isolation, with a limited number of beans loaded. Make sure to visit the Testing Java Code page for more interesting tutorials.
Video Lessons
I hope you found this tutorial helpful. If you prefer learning through video lessons, check out my course Testing Java with JUnit and Mockito. This course is designed for beginners and doesn’t require prior knowledge of testing Java applications. Additionally, you can find many other useful tutorials in the JUnit category on our website.
Happy learning!
Frequently asked questions
- What is the difference between a unit test and an integration test?
A unit test is a type of software test that focuses on testing individual components or units of code in isolation, typically using mocking or stubbing to simulate the behaviour of dependencies. In contrast, an integration test verifies the interaction and collaboration between different components or modules in the system, testing how they work together to achieve a specific functionality. Integration tests typically involve multiple components and require a more complex setup than unit tests. - Is @WebMvcTest a unit test or an integration test?
@WebMvcTest
is an integration test, specifically designed to test the Spring MVC web layer of a Spring Boot application in isolation. It does not load the entire application context, but rather a limited set of beans necessary for testing the web layer. - Can I use @SpringBootTest for testing the web layer of my Spring Boot application?
Yes, you can use@SpringBootTest
to test the web layer of your Spring Boot application. However,@WebMvcTest
is more suitable for testing the web layer in isolation, as it only loads the necessary beans for testing the web layer. On the other hand,@SpringBootTest
loads the entire application context, which includes all the beans in your application. - Is it necessary to use the @MockBean annotation with @WebMvcTest?
It depends on whether the controller being tested has any dependencies on services or repositories. If the controller does have dependencies, then those dependencies should be mocked using the@MockBean
annotation to ensure that the tests are isolated and the behaviour of the controller can be tested in isolation. If the controller does not have any dependencies, then the@MockBean
annotation is not necessary. - Can I use @WebMvcTest to test non-controller classes?
No, you cannot use@WebMvcTest
to test non-controller classes. It is specifically designed for testing the Spring MVC web layer of a Spring Boot application in isolation and, therefore, only loads a limited set of beans related to the web layer. If you need to test other parts of your application, you should use a different testing strategy or annotation. - What is the purpose of the webEnvironment attribute in the @SpringBootTest annotation?
ThewebEnvironment
attribute in the@SpringBootTest
annotation is used to specify the type of web environment to use when running the test. It has several options, includingMOCK
,RANDOM_PORT
, andDEFINED_PORT
. The default value isMOCK
, which means that the test will run with a mock web environment and will not start an embedded web server. The other options allow the test to run with a real web environment and an embedded web server, which can be useful for testing web requests and responses. - Can @SpringBootTest and @WebMvcTest be used together in the same test class?
Yes, you can use both@SpringBootTest
and@WebMvcTest
together in the same test class. However, be careful when using them together, as loading the full application context using@SpringBootTest
may cause redundant bean loading and slower test execution. It’s generally recommended to use only one of these annotations per test class, depending on your testing needs.