ecshop 属性自动组合_SpringBoot单元测试:MockMvc的自动配置

MockMvc 的自动配置

上面我们提到@AutoConfigureMockMvc 提供了自动配置 MockMvc 的功能,实例化MockMvc 的

具 体 代 码 在 spring-boot-test-autoconfigure 项 目 中 的MockMvcAutoConfiguration 自 动 配 置 类 内 。 而 该 自 动 配 置 类 的 生 效 又 涉 及 了@AutoConfigureMockMvc 注解。本节我们就大致来了解一下@AutoConfigureMockMvc 和MockMvcAutoConfiguration。

AutoConfigureMockMvc 注解

上节的例子中使用@AutoConfigureMockMvc 注解来引入启动单元测试的自动注入,从而注入 MockMvc 类的 Bean。那么,@AutoConfigureMockMvc 只是注入了 MockMvc 的 Bean吗?并不是的,我们来看一下

@AutoConfigureMockMvc 的源代码。@Target({ ElementType . TYPE,ElementType .METHOD })@Retent ion(RetentionPolicy . RUNTIME)@Documented@Inherited@ImportAutoConfiguration@PropertyMapping(" spring. test . mockmvc")public @interface AutoConfigureMockMvc {//是否应向 MockMVC 注册来自应用程序上下文的 filter,默认为 trueboolean addFilters() default true;// 每次 MockMVC 调用后应如何打 EMvcResult 信息@PropertyMapping(skip = SkipPropertyMapping .ON DEFAULT _VALUE)MockMvcPrint print() default MockMvcPrint . DEFAULT;//如果 MvcResult 仅在测试失败时才打印信息。true,则表示只在失败时打印boolean printOnlyOnFailure() default true;/当 HtmUnit 在类路径上时, 是否应该自动配置 webCliento 默认为 true@PropertyMapping( "webclient . enabled")boolean webClientEnabled() default true;//当 Selenium 位于类路径上时,是否应自动配置 WebDriver。默认 为 true@PropertyMapping("webdriver . enabled")boolean webDriverEnabled() default true;}

AutoConfigureMockMvc 中定义的属性比较简单,除了 print 属性是用于配置每次 MockMVC调用后打印 MvcResult 信息之外,其余的配置均为设置特定情况下是否进行相应处理。可结合上述代码中的注释部分了解对应属性的详细功能。同时,在上节的实例中(也是通常情况下)我们并没有进行特殊的配置,都采用该注解中的默认值。

在 AutoConfigureMockMvc 的源码中,我们重点看它组合的@ImportAutoConfiguration 注解 。 该 注 解 同 样 是 Spring Boot 自 动 配 置 项 目 提 供 的 , 其 功 能 类 似@EnableAutoCon-figuration,但又略有区别。

@lmportAutoConfiguration 同样用于导入自动配置类,不仅可以像@EnableAutoConfiguration 那样排除指定的自动配置类,还可以指定使用哪些自动配置类,这是它们之间的重要区别之一。

另外,@ImportAutoConfiguration 使用的排序规则与

@EnableAutoConfiguration 的相同,通常情况下,建议优先使用@EnableAutoConfiguration 注解进行自动配置。但在单元测试中,则可考虑优先使用@lmportAutoConfiguration。下面看 一下它的源码及功能,代码如下。@Target(ElementType . TYPE)@Retention( RetentionPolicy . RUNTIME)@Documented@Inherited@Import( ImportAutoConfigurationImportSelector. class)public @interface ImportAutoConfiguration {//指定引入的自动配置类@AliasFor("classes")Class>[] value() default {};//指定引入的自动配置类。如果为空,则使用 ME TA- INF/spring. factories 中注册的指定类//其中 spring. factories 中注册的 key 为被该注解的类的全限定名称@AliasFor("value")Class>[] classes() default {};/排除指定自动配置类Class>[] exclude() default {};}

上述代码中关于 ImportAutoConfiguration 导入的 Selector 与之前讲解@EnableAuto-Configuration 时的使用流程基本一致,我们不再赘述。

下面来看 ImportAutoConfiguration 中定义的属性。通过 value 属性,提供了指定自动配置类 的 功 能 , 可 以 通 过 细 粒 度 控 制 , 根 据 需 要 引 | 入 相 应 功 能 的 自 动 配 置 。 没 有@EnableAutoConfiguration-次注入全局生效的特性,但是有了指定的灵活性。

更值得注意的是 classes 属性,它也是用来指定自动配置类的,但它的特殊之处在于,如果未进行指定,则会默认搜索项目 ME TA-INF/spring.factories 文件中注册的类,但是它搜索的注册类在 spring.factories 中的 key 是被@ImportAutoConfiguration 注解的类的全限定名称。显然,这里的 key 为 org.springframework. boot.test.autoconfigure.web.servlet.Auto-ConfigureMockMvc 。 以 上 功 能 也 就 解 释 了 为 什 么 在 单 元 测 试 中 更 多 的 是 使 用@lmportAuto-Configuration 注解来进行自动配置了。

在 spring-boot-test-autoconfigure 项目的 spring.factories 文件中的相关配置如下。

# AutoConfigureMockMvc auto-configuration importsorg. springframework . boot . test . autoconfigure . web. servlet . AutoConf igureMockMvorg. springframework. boot . test . autoconfigure . web . servlet . MockMvcAutoConfiguration, org. springframework . boot . test . autoconfigure . web . servlet . MockMvcWebClientAutoCon-figuration, org . springframework. boot . test. autoconfigure . web . servlet. MockMvcWebDriverAutoCon-figuration, org. springframework . boot . autoconfigure . security. servlet. SecurityAutoConfiguration,org. springframework . boot . autoconfigure . security . servlet . UserDetailsServiceAuto-Configuration, org. springframework. boot . test . autoconfigure . web . servlet . MockMvcSecurityConfiguration

也就是说,当使用@lmportAutoConfiguration 注解,并未指定 classes 属性值时,默认自动配置上述自动配置类。

关 于 @ImportAutoConfiguration 我 们 就 讲 这 么 多 , 读 者 朋 友 可 以 对 照@EnableAuto-Configuration 相关章节中提供的方法,当作练习自行阅读该注解导入的ImportAutoConfi-gurationlmportSelector。下节我们以配置中的 MockMvcAutoConfiguration为例,讲解 MockMvc 相关的自动化配置。

9a06f8f9d6f538218c865048bc6b3153.png

MockMvcAutoConfiguration 自动配置

上 一 节 我 们 知 道 通 过 使 用 @AutoConfigureMockMvc 注 解 会 导 入MockMvcAutoCon-figuration 自动配置类,该类就是专门为 MockMvc 相关功能提供自动配置的。

先看 MockMvcAutoConfiguration 的注解和构造方法部分源代码。

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

注解部分说明,MockMvcAutoConfiguration 需 要在 Web 应用程序类型为 Servlet,且在WebMvcAutoConfiguration 自 动配置之后进行自动配置。关于 WebMvcAutoConfiguration我们在前面章节已经讲到,这里不再赘述。另 外 , 通 过 @EnableConfigurationProperties 导 入 了 ServerProperties 和WebMvcProperties 两个配置属性类,并通过构造方法设置为成员变量。

下面挑选 MockMvcAutoConfiguration 中几个比较重要的自动配置 Bean 来进行讲解,首先看 DispatcherServletPath 的注入。

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

当容器中不存在 DispatcherServletPath 的 Bean 时,会创建一个 DispatcherServletPath 实现 类 的 对 象 , 并 注 入 容 器 。 其 中 DispatcherServletPath 是 一 个 接 口 , 用 来 提 供DispatcherServlet 所需路径的详细信息。在上述代码中实现了 DispatcherServletPath 的getPath 方法,并返回 WebMvcProperties 配置:文件默认(“") 或指定的 Web 访问路径。

MockMvc 主 要 是 通 过 MockMvcBuilder 创 建 的 , 默 认 情 况 下 实 例 化 了DefaultMock-MvcBuilder,相关代码如下。

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

当 容 器 中 不 存 在 MockMvcBuilder 的 Bean 时 , 通 过 MockMvcBuilders 的webAppContextSetup 方法创建 DefaultMockMvcBuilder ,然后设置 DispatcherServlet 和MockMvcBuilder 的 定 制 化 配 置 。 其 中 , 关 于 DispatcherServlet 的 设 置 就 在MockMvcAutoConfiguration 中定义,其核心代码如下。

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

上述代码就是对配置文件 WebMvcProperties 中 DispatcherServlet 是 否 分 发“HTTPOPTIONS"请求、是否分发“HTTPTRACE"、是否抛出 NoHandlerFoundException进行配置。

当获得了 MockMvcBuilder,便可以配置并实例化 MockMvc 了,相关代码如下。

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

至此,MockMvc 已经被实例化并注入容器了。 当然,如果容器中不存在 DispatcherServlet对应的 Bean, 也会进行相应的自动配置。

@Bean@ConditionalOnMissingBeanpublicDi spatcherServlet dispatcherServlet (MockMvc mockMvc) {return mockMvc . getDispatcherServlet();}

这里是通过 MockMvc 提供的方法来获得 DispatcherServlet 的 Bean,并注册。

正是有了上述自动配置机制,我们在单元测试时直接在单元测试类上使用@AutoCon-figureMockMvc 注解之后,便可以直接通过@Autowired 对 MockMvc 进行注入并使用了。

c73fdf1274700630dcf1bd1ed3db6c21.png

小结

本章简单地介绍了 Spring Boot 中对单元测试的支持,以及常用的注解、单元测试实例。关于单元测试开启及自动注入我们讲解了@AutoConfigureMockMvc。 类似的,Spring Boot还提供了许多更加有针对性、使用快捷的注解,比如:针对 JSON 的@JsonTest、 针对 MVC的@WebMvcTest、针对 WebFlux 的@WebFluxTest、 针对 Data JPA 的@DataJpaTest 、针 对 JDBC 的 @JdbcTest 针 对 MongoDB 的 @DataMongoTest 、 针 对 redis 的@DataRedisTest 等 。 但 如 果 我 们 阅 读 上 述 注 解 的 源 码 , 会 发 现 其 处 理 机 制 与@AutoConfigureMockMvc 基 本一致 , 核 心 部分都使用了本章讲到的@ImportAutoConfiguration 注解。

本章的重点并不仅仅是要教会大家如何使用单元测试,更重要的是传达个思想:单元测试是保证代码质量的重要方式,在具体项目中,如果有可能,请尽量编写单元测试代码。

34b4cacc7127c61ca83a7fdfe26461e0.png

本文给大家讲解的内容是SpringBoot单元测试:MockMvc的自动配置

  1. 下篇文章给大家讲解的是SpringBoot 打包部署解析;
  2. 觉得文章不错的朋友可以转发此文关注小编;
  3. 感谢大家的支持!
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值