spring boot测试

如果您或多或少有经验的Spring Boot用户,那么很幸运,在某些时候您可能需要遇到必须有条件地注入特定bean或配置的情况 。 它的机制是很好理解的 ,但有时这样的测试条件下(以及它们的组合)可能会导致混乱。 在这篇文章中,我们将讨论一些可行的方法(可以说是理智的)。

由于Spring Boot 1.5.x仍被广泛使用(不过,它将在今年8月向EOL迈进),因此我们会将其与Spring Boot 2.1.x一起包括在JUnit 4.x和JUnit 5.x中 。 我们将要介绍的技术同样适用于常规配置类和自动配置类。

我们将使用的示例与我们的自制日志记录有关。 让我们假设我们的Spring Boot应用程序需要一些名称为“ sample”的专用记录器bean。 但是,在某些情况下,必须禁用此记录器(或实际上使其成为noop),因此在这里,属性logging.enabled就像一个kill开关。 在此示例中,我们使用Slf4j和Logback ,但这并不是很重要。 下面的LoggingConfiguration片段反映了这个想法。

 @Configuration  public class LoggingConfiguration { @Configuration @ConditionalOnProperty (name = "logging.enabled" , matchIfMissing = true ) public static class Slf4jConfiguration { @Bean Logger logger() { return LoggerFactory.getLogger( "sample" ); } }     @Bean @ConditionalOnMissingBean Logger logger() { return new NOPLoggerFactory().getLogger( "sample" ); }  } 

那么我们将如何测试呢? Spring Boot (通常是Spring Framework )一直提供出色的测试脚手架支持 。 @SpringBootTest@TestPropertySource批注允许使用自定义属性快速引导应用程序上下文。 但是,有一个问题:它们是按测试类级别而不是每种测试方法应用的。 这当然是有道理的,但基本上需要您为每个条件组合创建一个测试类。

如果您仍然使用JUnit 4.x ,则可能会发现一个有用的技巧,它可以利用框架的隐藏的宝石EnclosedRunner

 @RunWith (Enclosed. class (Enclosed. )  public class LoggingConfigurationTest { @RunWith (SpringRunner. class ) @SpringBootTest public static class LoggerEnabledTest { @Autowired private Logger logger;         @Test public void loggerShouldBeSlf4j() { assertThat(logger).isInstanceOf(ch.qos.logback.classic.Logger. class ); } }     @RunWith (SpringRunner. class ) @SpringBootTest @TestPropertySource (properties = "logging.enabled=false" ) public static class LoggerDisabledTest { @Autowired private Logger logger;         @Test public void loggerShouldBeNoop() { assertThat(logger).isSameAs(NOPLogger.NOP_LOGGER); } }  } 

您仍然可以按条件获得类,但至少它们都在同一嵌套中。 使用JUnit 5.x ,有些事情变得容易了,但并没有达到人们期望的水平。 不幸的是, Spring Boot 1.5.x本身并不支持JUnit 5.x ,因此我们必须依靠spring-test-junit5社区模块提供的扩展。 这是pom.xml中的相关更改,请注意, spring-boot-starter-test依赖关系图中明确排除了junit

 < dependency > < groupId >org.springframework.boot</ groupId > < artifactId >spring-boot-starter-test</ artifactId > < scope >test</ scope > < exclusions > < exclusion > < groupId >junit</ groupId > < artifactId >junit</ artifactId > </ exclusion > </ exclusions >  </ dependency >  < dependency > < groupId >com.github.sbrannen</ groupId > < artifactId >spring-test-junit5</ artifactId > < version >1.5.0</ version > < scope >test</ scope >  </ dependency >  < dependency > < groupId >org.junit.jupiter</ groupId > < artifactId >junit-jupiter-api</ artifactId > < version >5.5.0</ version > < scope >test</ scope >  </ dependency >  < dependency > < groupId >org.junit.jupiter</ groupId > < artifactId >junit-jupiter-engine</ artifactId > < version >5.5.0</ version > < scope >test</ scope >  </ dependency > 

除了使用@Nested批注(来自JUnit 5.x以支持将测试作为内部类)外,测试用例本身没有太大区别。

 public class LoggingConfigurationTest { @Nested @ExtendWith (SpringExtension. class ) @SpringBootTest @DisplayName ( "Logging is enabled, expecting Slf4j logger" ) public static class LoggerEnabledTest { @Autowired private Logger logger;         @Test public void loggerShouldBeSlf4j() { assertThat(logger).isInstanceOf(ch.qos.logback.classic.Logger. class ); } }     @Nested @ExtendWith (SpringExtension. class ) @SpringBootTest @TestPropertySource (properties = "logging.enabled=false" ) @DisplayName ( "Logging is disabled, expecting NOOP logger" ) public static class LoggerDisabledTest { @Autowired private Logger logger;         @Test public void loggerShouldBeNoop() { assertThat(logger).isSameAs(NOPLogger.NOP_LOGGER); } }  } 

如果您尝试使用Apache Maven和Maven Surefire插件从命令行运行测试,则可能会惊讶地发现在构建过程中没有执行任何测试。 问题是… 排除了所有嵌套类 …因此我们需要采用另一种解决方法 。

 < plugin > < groupId >org.apache.maven.plugins</ groupId > < artifactId >maven-surefire-plugin</ artifactId > < version >2.22.2</ version > < configuration > < excludes > < exclude /> </ excludes > </ configuration >  </ plugin > 

这样,事情应该顺利进行。 但是关于传统的足够多, Spring Boot 2.1.x可以作为完整的游戏改变者。 上下文运行程序家族ApplicationContextRunnerReactiveWebApplicationContextRunnerWebApplicationContextRunner提供了一种简单明了的方法来按每个测试方法级别定制上下文,从而使测试的执行速度非常快。

 public class LoggingConfigurationTest { private final ApplicationContextRunner runner = new ApplicationContextRunner() .withConfiguration(UserConfigurations.of(LoggingConfiguration. class ));     @Test public void loggerShouldBeSlf4j() { runner .run(ctx -> assertThat(ctx.getBean(Logger. class )).isInstanceOf(Logger. class ) ); }     @Test public void loggerShouldBeNoop() { runner .withPropertyValues( "logging.enabled=false" ) .run(ctx -> assertThat(ctx.getBean(Logger. class )).isSameAs(NOPLogger.NOP_LOGGER) ); }  } 

看起来真的很棒。 Spring Boot 2.1.x对JUnit 5.x的支持要好得多,并且即将推出的2.2 发布时, JUnit 5.x将是默认引擎 (不用担心,仍将支持旧的JUnit 4.x )。 到目前为止,切换到JUnit 5.x需要在依赖项方面进行一些工作。

 < dependency > < groupId >org.springframework.boot</ groupId > < artifactId >spring-boot-starter-test</ artifactId > < scope >test</ scope > < exclusions > < exclusion > < groupId >junit</ groupId > < artifactId >junit</ artifactId > </ exclusion > </ exclusions >  </ dependency >  < dependency > < groupId >org.junit.jupiter</ groupId > < artifactId >junit-jupiter-api</ artifactId > < scope >test</ scope >  </ dependency >  < dependency > < groupId >org.junit.jupiter</ groupId > < artifactId >junit-jupiter-engine</ artifactId > < scope >test</ scope >  </ dependency > 

作为附加步骤,您可能需要使用最新的Maven Surefire插件 ( 2.22.0或更高版本)以及现成的JUnit 5.x支持。 下面的代码段说明了这一点。

 < plugin > < groupId >org.apache.maven.plugins</ groupId > < artifactId >maven-surefire-plugin</ artifactId > < version >2.22.2</ version >  </ plugin > 

我们使用的示例配置非常幼稚,许多实际应用程序最终将具有由许多条件构建而成的非常复杂的上下文。 上下文赛跑者带来的灵活性和巨大的机会, Spring Boot 2.x测试脚手架的宝贵补充,只是活泼的救星,请紧记它们。

完整的项目资源可在Github上找到 。

翻译自: https://www.javacodegeeks.com/2019/08/testing-spring-boot-conditionals-sane-way.html

spring boot测试

spring boot测试_测试Spring Boot有条件的合理方式相关推荐

  1. spring 事务 会话_测试Spring的“会话”范围

    spring 事务 会话 在基于Spring的Web应用程序中,bean的作用域可以是用户"会话". 从本质上讲,这意味着对会话范围Bean的状态更改仅在用户会话范围内可见. 本条 ...

  2. 机器学习 测试_测试优先机器学习

    机器学习 测试 Testing software is one of the most complex tasks in software engineering. While in traditio ...

  3. spring mysql 注解_【Spring】SpringMVC之基于注解的实现SpringMVC+MySQL

    目录结构: contents structure [-] SpringMVC是什么 MVC的全称是Model View Controller,通过实现MVC框架可以很好的数据.视图.业务逻辑进行分离. ...

  4. spring生命周期_理解Spring应用上下文生命周期

    Spring应用上下文启动准备阶段 `BeanFactory`创建阶段 `BeanFactory`准备阶段 `BeanFactory`后置处理阶段 `AnnotationConfigServletWe ...

  5. springboot2 使用hikaridatasource 并测试_基于Spring Boot 2.x的后端管理网站脚手,源码免费分享...

    基于Spring Boot 2.x 的 Material Design 的后端管理网站脚手架 :提供权限认证 用户管理 菜单管理 操作日志 等常用功能 去繁就简 重新出发 基于Spring Boot ...

  6. spring boot注释_使用Spring Boot和注释支持配置Spring JMS应用程序

    spring boot注释 1.简介 在以前的文章中,我们学习了如何使用Spring JMS配置项目. 如果查看有关使用Spring JMS进行消息传递的文章介绍 ,您会注意到它是使用XML配置的. ...

  7. java+spring+mysql配置_用spring的beans配置mysql数据库

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www. ...

  8. spring 计划任务_与Spring的计划任务一起按时运行

    spring 计划任务 您是否需要每天像闹钟一样在同一时间运行某个流程? 然后,Spring的预定任务适合您. 允许您使用@Scheduled注释方法,以使其在指定的时间或内部间隔运行. 在本文中,我 ...

  9. spring 异常捕获异常_使用Spring跟踪异常–第2部分–委托模式

    spring 异常捕获异常 在上一个博客中 ,我开始谈论需要弄清您的应用程序在生产环境中是否行为异常. 我说过,监视应用程序的一种方法是检查其日志文件是否存在异常,如果发现异常,则采取适当的措施. 显 ...

最新文章

  1. leetcode-232 用栈实现队列
  2. 在selenium中使用css选择器进行元素定位(一)
  3. mysql索引 物理文件_MySQL架构和MySQL索引
  4. 淘淘商城项目过程记录
  5. Go语言通过odbc驱动连接华为高斯数据库
  6. 华东电脑申威服务器_华东电脑(600850):申威服务器首批量产下线 国产化业务落地里程碑事件[配资公司会议室]...
  7. sqlserver日志文件在哪_用友SQL SERVER数据库置疑修复实例
  8. 伪题解 洛谷 P1363 幻想迷宫(DFS)
  9. idea改类名快捷键_IDEA使用之快捷键(default设置)
  10. 我的世界逆时空服务器怎么注册密码,我的世界1.7.10服务器逆时空
  11. PEGASUS: Pre-training with Extracted Gap-sentences for Abstractive Summarization
  12. 关于verilog中综合的过程,可综合与不可综合的理解
  13. 时空、光年、过去与现在
  14. 作为一本书,我是如何把别的Java系列卷死的!
  15. 图像频率域分析之频域谱(FDE)
  16. 5613-2-冒泡排序
  17. 国内有哪些VPS值得推荐?
  18. 深度相机(一)--TOF总结
  19. 怎么修改证件照尺寸?这里种修改尺寸方法值得收藏
  20. 她们用实力,打破了科技圈的女性职场天花板

热门文章

  1. CF708E-Student‘s Camp【数学期望,dp】
  2. ssl1715-计算面积【差积】
  3. 2017西安交大ACM小学期 刷墙[折半枚举+异或]
  4. 动态规划训练21 [FatMouse and Cheese HDU - 1078 ]
  5. 18、数据的备份和还原
  6. 彻底理解JVM常考题之分级引用模型
  7. JavaFX UI控件教程(六)之Toggle Button
  8. Oracle入门(五E)之讲解show parameter命令模糊查询
  9. 装饰器模式和代理模式的区别
  10. 装饰器模式(讲解+应用)