MVC's automatic test unit configuration: SpringBoot

Automatic configuration of MockMvc

As mentioned above, @ AutoConfigureMockMvc provides the function of automatically configuring MockMvc and instantiating the function of MockMvc

The specific code is in
Within the MockMvcAutoConfiguration autoconfiguration class in the spring boot test autoconfiguration project. The effectiveness of this automatic configuration class involves the @ AutoConfigureMockMvc annotation. In this section, we will learn about @ AutoConfigureMockMvc and MockMvcAutoConfiguration.

AutoConfigureMockMvc annotation

In the example in the previous section, the @ AutoConfigureMockMvc annotation is used to introduce the automatic injection of starting unit tests, so as to inject beans of the MockMvc class. So, @ AutoConfigureMockMvc just injected the Bean of MockMvc? No, let's take a look

@AutoConfigureMockMvc Source code.
@Target({ ElementType . TYPE,ElementType .METHOD })
@Retent ion(RetentionPolicy . RUNTIME)@Documented
@Inherited
@ImportAutoConfiguration
@PropertyMapping(" spring. test . mockmvc")
public @interface AutoConfigureMockMvc {
//Whether the filter from the application context should be registered with MockMVC. The default is true
boolean addFilters() default true;
// How to type EMvcResult information after each MockMVC call
@PropertyMapping(skip = SkipPropertyMapping .ON DEFAULT _VALUE)
MockMvcPrint print() default MockMvcPrint . DEFAULT;
//If MvcResult, the message is printed only when the test fails. true, it means to print only in case of failure
boolean printOnlyOnFailure() default true;
/When HtmUnit Should it be automatically configured when on the classpath webCliento Default to true
@PropertyMapping( "webclient . enabled")
boolean webClientEnabled() default true;
//Whether WebDriver should be automatically configured when Selenium is on the classpath. The default is true
@PropertyMapping("webdriver . enabled")
boolean webDriverEnabled() default true;
}

The attributes defined in AutoConfigureMockMvc are relatively simple. Except that the print attribute is used to configure the printing of MvcResult information after each MockMVC call, other configurations are to set whether to process it accordingly under specific circumstances. You can understand the detailed functions of the corresponding attributes in combination with the comments in the above code. At the same time, in the example in the previous section (also generally), we do not have special configuration, and we all use the default value in the annotation.

In the source code of AutoConfigureMockMvc, we focus on its combined @ ImportAutoConfiguration annotation. This annotation is also provided by the Spring Boot auto configuration project. Its function is similar to @ enableautocon configuration, but slightly different.

@lmportAutoConfiguration is also used to import autoconfiguration classes. It can not only exclude the specified autoconfiguration classes like @ EnableAutoConfiguration, but also specify which autoconfiguration classes to use, which is one of the important differences between them.

In addition, @ ImportAutoConfiguration uses the same collation as

@EnableAutoConfiguration In general, it is recommended to give priority to use
@EnableAutoConfiguration Annotations are automatically configured. However, in unit testing, it can be used preferentially
@lmportAutoConfiguration. Let's take a look at its source code and functions. The code is as follows.
@Target(ElementType . TYPE)
@Retention( RetentionPolicy . RUNTIME)
@Documented@Inherited
@Import( ImportAutoConfigurationImportSelector. class)
public @interface ImportAutoConfiguration {
//Specifies the imported autoconfiguration class
@AliasFor("classes")
Class<?>[] value() default {};
//Specifies the imported autoconfiguration class. If empty, use me ta - inf / spring Specified class registered in factories
//Including spring The key registered in factories is the fully qualified name of the annotated class
@AliasFor("value")
Class<?>[] classes() default {};
/Exclude specified autoconfiguration classes
Class<?>[] exclude() default {};
}

The Selector of ImportAutoConfiguration in the above code is basically the same as the use process of @ enableauto configuration, which will not be repeated.

Let's look at the properties defined in ImportAutoConfiguration. The value attribute provides the function of specifying the automatic configuration class. Through fine-grained control, the automatic configuration of corresponding functions can be introduced as needed. There is no feature of @ EnableAutoConfiguration - once injection global effect, but it has the specified flexibility.

What is more noteworthy is the classes attribute, which is also used to specify the automatic configuration class, but its special feature is that if it is not specified, the default search item me ta-inf / spring. Is used The classes registered in the factories file, but the registered classes it searches for are in spring The key in factories is the fully qualified name of the class annotated by @ ImportAutoConfiguration. Obviously, the key here is org springframework.
boot.test.autoconfigure.web.servlet.Auto-ConfigureMockMvc . The above functions explain why the @ lmportauto configuration annotation is more used for automatic configuration in unit testing.

stay
Spring. Of spring boot test autoconfigure project The relevant configurations in the factories file are as follows.

# AutoConfigureMockMvc auto-configuration imports
org. springframework . boot . test . autoconfigure . web. servlet . AutoConf igureMockMv
org. springframework. boot . test . autoconfigure . web . servlet . MockMvcAutoConfigur
ation, \
org. springframework . boot . test . autoconfigure . web . servlet . MockMvcWebClientAut
oCon-
figuration, \
org . springframework. boot . test. autoconfigure . web . servlet. MockMvcWebDriverAut
oCon-
figuration, \
org. springframework . boot . autoconfigure . security. servlet. SecurityAutoConfiguration,\
org. springframework . boot . autoconfigure . security . servlet . UserDetailsServiceA
uto-
Configuration, \
org. springframework. boot . test . autoconfigure . web . servlet . MockMvcSecurity
Configuration

That is, when the @ lmportAutoConfiguration annotation is used and the classes attribute value is not specified, the above autoconfiguration classes are automatically configured by default.

Let's talk so much about @ ImportAutoConfiguration. Readers can refer to the methods provided in the relevant chapters of @ enableauto configuration as an exercise to read the imported annotation by themselves
ImportAutoConfi-gurationlmportSelector. In the next section, we will take the MockMvcAutoConfiguration in configuration as an example to explain the automatic configuration related to MockMvc.

MockMvcAutoConfiguration autoconfiguration

In the previous section, we know that the @ AutoConfigureMockMvc annotation will import the mockmvcautocon configuration automatic configuration class, which is designed to provide automatic configuration for the relevant functions of MockMvc.

Let's first look at the annotation and construction method part of the source code of mockmvccautoconfiguration.

@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type . SERVLET)
@AutoConfigureAfter (WebMvcAutoConfiguration. class)
@EnableConfigurationProperties({ ServerProperties. class, WebMvcProperties.c
lass } )
public class MockMvcAutoConfiguration {
private final WebApplicationContext context;
private final WebMvcProperties webMvcProperties;
MockMvcAutoConfiguration(WebApplicationContext context, WebMvcProperties
webMvcProperties) {
this. context = context;
this
. webM
Properties = webMvcProperties; }}

Note that mockmvcoautoconfiguration needs to be automatically configured after the Web application type is Servlet and webmvcoautoconfiguration is automatically configured. We have talked about webmvcoautoconfiguration in the previous chapter, so we won't repeat it here. In addition, through@
EnableConfigurationProperties imports two configuration property classes, ServerProperties and WebMvcProperties, and sets them as member variables through the construction method.

Next, select several important automatic configuration beans in mockmvccautoconfiguration to explain. First, look at the injection of DispatcherServletPath.

@Bean
@Condit ional0nMi ssingBean
public DispatcherServletPath dispatcherServletPath() {
return () -> this . webMvcProperties . getServlet() . getPath();}

When the Bean of DispatcherServletPath does not exist in the container, an object of the implementation class of DispatcherServletPath will be created and injected into the container. DispatcherServletPath is an interface used to provide details of the path required by DispatcherServlet. In the above code, the getPath method of DispatcherServletPath is implemented, and the WebMvcProperties configuration file is returned: the default (") or the specified Web access path.

MockMvc is mainly created through MockMvcBuilder. Defaultmock mvcbuilder is instantiated by default. The relevant codes are as follows.

@Bean
@Conditional0nMi ssingBean(MockMvcBuilder . class)
public DefaultMockMvcBuilder mockMvcBuilder(List<MockMvcBuilderCustomizer>
customizers) {
DefaultMockMvcBuilder builder = MockMvcBuilders . webAppContextSetup(this. (
ontext) ;
builder . addDispatcherServletCustomizer (new MockMvcDi spatcherServletCusto-
mizer(this . webMvcProperties));
for (MockMvcBuilderCustomizer customizer : customizers) {
customizer. customize(builder);}
return builder;}

When the Bean of MockMvcBuilder does not exist in the container, create DefaultMockMvcBuilder through the webAppContextSetup method of MockMvcBuilders, and then set the customized configuration of DispatcherServlet and MockMvcBuilder. The settings of DispatcherServlet are defined in mockmvccautoconfiguration, and its core code is as follows.

@Override
public void customize(DispatcherServlet dispatcherServlet) {
dispatcherServlet . setDispatchOptionsRequest(this . webMvcProperties . isDispa
tch-
Opt ionsRequest());
dispatcherServlet . setDi spatchTraceRequest(this . webMvcProperties . isDispa-tchTraceRequest());
dispatcherServlet
. setThrowExceptionIfNoHandlerFound( this . webMvcProperties . isThrowExcep-
tionIfNoHandlerFound());
}

The above code is to configure whether DispatcherServlet distributes "HTTPOPTIONS" request, whether to distribute "HTTPTRACE" and whether to throw NoHandlerFoundException in the configuration file WebMvcProperties.

After obtaining MockMvcBuilder, you can configure and instantiate MockMvc. The relevant codes are as follows.

@Bean
@ConditionalOnMi ssingBean
public MockMvc mockMvc (MockMvcBuilder builder) {
return builder . build(); }

So far, MockMvc has been instantiated and injected into the container. Of course, if the Bean corresponding to the dispatcher servlet does not exist in the container, it will also be automatically configured accordingly.

@Bean
@ConditionalOnMissingBean
public
Di spatcherServlet dispatcherServlet (MockMvc mockMvc) {
return mockMvc . getDispatcherServlet();
}

Here is the method provided by MockMvc to obtain and register the Bean of DispatcherServlet.

With the above automatic configuration mechanism, we can inject and use MockMvc directly through @ Autowired after using @ autocon figuremockmvc annotation directly on the unit test class during unit test.

Summary

This chapter briefly introduces the support for unit testing in Spring Boot, as well as common annotations and unit test examples. About unit test startup and automatic injection, we explained @ AutoConfigureMockMvc. Similarly, Spring Boot also provides many more targeted and quick annotations, such as @ JsonTest for JSON, @ WebMvcTest for MVC, @ WebFluxTest for WebFlux, @ DataJpaTest for Data JPA, @ JdbcTest for JDBC, @ datamongote for MongoDB, @ DataRedisTest for redis, etc. However, if we read the source code of the above annotation, we will find that its processing mechanism is basically the same as @ AutoConfigureMockMvc, and the @ ImportAutoConfiguration annotation mentioned in this chapter is used in the core part.

The focus of this chapter is not only to teach you how to use unit testing, but also to convey an idea: unit testing is an important way to ensure code quality. In specific projects, if possible, please try to write unit testing code.

The content of this article is SpringBoot unit test: automatic configuration of MockMvc

  1. The next article will explain to you the spring boot packaging deployment analysis;
  2. Friends who think the article is good can forward this article and pay attention to the Xiaobian;
  3. Thank you for your support!

Keywords: Java Programming Spring Boot Programmer unit testing

Added by zelot1980 on Sat, 19 Feb 2022 10:04:28 +0200