原文: http://zetcode.com/spring/springrunner/

SpringRunner教程展示了如何使用SpringRunner测试 Spring 应用。

Spring 是流行的 Java 应用框架。 在本教程中,我们使用 Spring 5 版本。

SpringRunner

SpringRunnerSpringJUnit4ClassRunner的别名,该别名将JUnit测试库与 Spring TestContext Framework 结合在一起。 我们将其与@RunWith(SpringRunner.class)一起使用。

使用SpringRunner,我们可以实现基于 JUnit 4 的标准单元测试和集成测试。

Spring TestContext Framework 提供了通用的,注解驱动的单元和集成测试支持,这些支持与使用中的测试框架(JUnit,TestNG)无关。

SpringRunner示例

在以下应用中,我们使用SprigRunner测试一个简单的服务。 该应用是一个 Spring 独立控制台应用。

该应用包含两个属性文件:一个文件用于生产应用,另一个文件用于测试。

  1. pom.xml
  2. src
  3. ├───main
  4. ├───java
  5. └───com
  6. └───zetcode
  7. Application.java
  8. ├───config
  9. AppConfig.java
  10. └───service
  11. HelloService.java
  12. └───resources
  13. application.properties
  14. logback.xml
  15. └───test
  16. ├───java
  17. └───com
  18. └───zetcode
  19. └───service
  20. HelloServiceTest.java
  21. └───resources
  22. appTest.properties

这是项目结构。

pom.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
  5. http://maven.apache.org/xsd/maven-4.0.0.xsd">
  6. <modelVersion>4.0.0</modelVersion>
  7. <groupId>com.zetcode</groupId>
  8. <artifactId>springrunnerex</artifactId>
  9. <version>1.0-SNAPSHOT</version>
  10. <packaging>jar</packaging>
  11. <properties>
  12. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  13. <maven.compiler.source>11</maven.compiler.source>
  14. <maven.compiler.target>11</maven.compiler.target>
  15. <spring-version>5.1.3.RELEASE</spring-version>
  16. </properties>
  17. <dependencies>
  18. <dependency>
  19. <groupId>ch.qos.logback</groupId>
  20. <artifactId>logback-classic</artifactId>
  21. <version>1.2.3</version>
  22. </dependency>
  23. <dependency>
  24. <groupId>org.springframework</groupId>
  25. <artifactId>spring-context</artifactId>
  26. <version>${spring-version}</version>
  27. </dependency>
  28. <dependency>
  29. <groupId>org.springframework</groupId>
  30. <artifactId>spring-core</artifactId>
  31. <version>${spring-version}</version>
  32. </dependency>
  33. <dependency>
  34. <groupId>org.springframework</groupId>
  35. <artifactId>spring-test</artifactId>
  36. <version>${spring-version}</version>
  37. </dependency>
  38. <dependency>
  39. <groupId>org.hamcrest</groupId>
  40. <artifactId>hamcrest-all</artifactId>
  41. <version>1.3</version>
  42. <scope>test</scope>
  43. </dependency>
  44. <dependency>
  45. <groupId>junit</groupId>
  46. <artifactId>junit</artifactId>
  47. <version>4.12</version>
  48. <scope>test</scope>
  49. </dependency>
  50. </dependencies>
  51. <build>
  52. <plugins>
  53. <plugin>
  54. <groupId>org.codehaus.mojo</groupId>
  55. <artifactId>exec-maven-plugin</artifactId>
  56. <version>1.6.0</version>
  57. <configuration>
  58. <mainClass>com.zetcode.Application</mainClass>
  59. </configuration>
  60. </plugin>
  61. </plugins>
  62. </build>
  63. </project>

这是 Maven 构建文件。 我们具有以下依赖项:logback-classic用于记录日志,spring-contextspring-core是基本的 Spring 依赖项,spring-test用于测试,hamcrest-all包含 Hamcrest 匹配库的所有模块,而JUnit是用于单元测试的库。

exec-maven-plugin帮助执行系统和 Java 程序。

resources/logback.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <configuration>
  3. <logger name="org.springframework" level="ERROR"/>
  4. <logger name="com.zetcode" level="INFO"/>
  5. <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
  6. <encoder>
  7. <Pattern>%d{HH:mm:ss.SSS} %blue(%-5level) %magenta(%logger{36}) - %msg %n
  8. </Pattern>
  9. </encoder>
  10. </appender>
  11. <root>
  12. <level value="INFO" />
  13. <appender-ref ref="consoleAppender" />
  14. </root>
  15. </configuration>

logback.xml是 Logback 日志库的配置文件。

resources/application.properties

  1. app.message=Hello there!

application.properties包含一个消息属性,由HelloMessage服务显示。

com/zetcode/AppConfig.java

  1. package com.zetcode.config;
  2. import org.springframework.context.annotation.ComponentScan;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.context.annotation.PropertySource;
  5. @Configuration
  6. @ComponentScan(basePackages = "com.zetcode")
  7. @PropertySource("application.properties")
  8. public class AppConfig {
  9. }

AppConfig配置组件扫描并从提供的文件中加载属性。

com/zetcode/servide/HelloService.java

  1. package com.zetcode.service;
  2. import org.springframework.beans.factory.annotation.Value;
  3. import org.springframework.stereotype.Service;
  4. @Service
  5. public class HelloService {
  6. @Value("${app.message}")
  7. private String message;
  8. public String sayHello() {
  9. return message;
  10. }
  11. }

HelloService返回从application.properties文件检索到的消息。

com/zetcode/Application.java

  1. package com.zetcode;
  2. import com.zetcode.config.AppConfig;
  3. import com.zetcode.service.HelloService;
  4. import org.slf4j.Logger;
  5. import org.slf4j.LoggerFactory;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.context.annotation.AnnotationConfigApplicationContext;
  8. import org.springframework.stereotype.Component;
  9. @Component
  10. public class Application {
  11. private static final Logger logger = LoggerFactory.getLogger(Application.class);
  12. public static void main(String[] args) {
  13. var ctx = new AnnotationConfigApplicationContext(AppConfig.class);
  14. var app = ctx.getBean(Application.class);
  15. app.run();
  16. ctx.close();
  17. }
  18. @Autowired
  19. private HelloService helloService;
  20. private void run() {
  21. logger.info("Calling hello service");
  22. logger.info(helloService.sayHello());
  23. }
  24. }

应用使用HelloService将消息打印到控制台。

  1. $ mvn -q exec:java
  2. 17:50:54.118 INFO com.zetcode.Application - Calling hello service
  3. 17:50:54.118 INFO com.zetcode.Application - Hello there!

我们运行该应用。

resources/appTest.properties

  1. app.message=Testing hello message

appTest.properties专用于测试。

com/zetcode/service/HelloServiceTest.java

  1. package com.zetcode.service;
  2. import com.zetcode.config.AppConfig;
  3. import org.junit.Test;
  4. import org.junit.runner.RunWith;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.beans.factory.annotation.Value;
  7. import org.springframework.test.context.ContextConfiguration;
  8. import org.springframework.test.context.TestPropertySource;
  9. import org.springframework.test.context.junit4.SpringRunner;
  10. import static org.hamcrest.CoreMatchers.equalTo;
  11. import static org.junit.Assert.assertThat;
  12. @RunWith(SpringRunner.class)
  13. @ContextConfiguration(classes={HelloService.class})
  14. @TestPropertySource("/appTest.properties")
  15. public class HelloServiceTest {
  16. @Value("${app.message}")
  17. private String message;
  18. @Autowired
  19. private HelloService helloService;
  20. @Test
  21. public void testHelloMessage() {
  22. var message = helloService.sayHello();
  23. assertThat(message, equalTo(message));
  24. }
  25. }

HelloServiceTest用于测试HelloService类。

  1. @RunWith(SpringRunner.class)
  2. @ContextConfiguration(classes={HelloService.class})
  3. @TestPropertySource("/appTest.properties")
  4. public class HelloServiceTest {

测试类用@RunWith(SpringRunner.class)注解。 @ContextConfiguration定义了类级别的元数据,用于确定如何加载和配置用于集成测试的应用上下文。 此外,我们还提供了@TestPropertySource自定义测试属性文件。

  1. @Value("${app.message}")
  2. private String message;

我们从appTest.properties文件注入消息。

  1. @Autowired
  2. private HelloService helloService;

我们注入HelloMessage服务类。 这是要测试的类。

  1. @Test
  2. public void testHelloMessage() {
  3. var message = helloService.sayHello();
  4. assertThat(message, equalTo(message));
  5. }

我们测试来自service方法的消息是否等于注入的字符串值。

  1. $ mvn -q test
  2. -------------------------------------------------------
  3. T E S T S
  4. -------------------------------------------------------
  5. Running com.zetcode.service.HelloServiceTest
  6. Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.489 sec
  7. Results :
  8. Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

我们运行测试。

在本教程中,我们展示了如何使用SpringRunner在 Spring 应用中创建测试。 Spring MockMvc 教程Spring @PropertySource教程Java 教程