javascript
spring boot测试_测试Spring Boot有条件的合理方式
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可以作為完整的游戲改變者。 上下文運行程序家族ApplicationContextRunner , ReactiveWebApplicationContextRunner和WebApplicationContextRunner提供了一種簡單明了的方法來按每個測試方法級別定制上下文,從而使測試的執行速度非常快。
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有条件的合理方式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 10寸笔记本电脑(三星10寸笔记本电脑)
- 下一篇: gradle idea java ssm