Difference Between @SpringBootTest and @WebMvcTest

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?
    The webEnvironment attribute in the @SpringBootTest annotation is used to specify the type of web environment to use when running the test. It has several options, including MOCK, RANDOM_PORT, and DEFINED_PORT. The default value is MOCK, 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.