springboot系列学习笔记全部文章请移步值博主专栏**: spring boot 2.X/spring cloud Greenwich

由于是一系列文章,所以后面的文章可能会使用到前面文章的项目。springboot系列代码全部上传至GitHub:https://github.com/liubenlong/springboot2_demo

本系列环境:Java11;springboot 2.1.1.RELEASE;springcloud Greenwich.RELEASE;MySQL 8.0.5;

单元测试和日志比较简单,放到一起讲一下。本篇文章需要使用到Junit、TestNg、Mockito、Spring Testing,本文不会对其使用进行特别详细的说明,请自行检索

日志

springboot官方文档中指出,如果我们使用Starters,那么默认使用Logback作为日志输出组件。当然还支持Commons Logging, Log4J等组件。

简单日志配置(包含了指定文件目录, 格式,以及level):

  1. logging:
  2. level:
  3. root: info
  4. com.example.controller: info
  5. com.example.service: warn
  6. file: d://a.log
  7. pattern:
  8. console: "%d - %msg%n"

springboot中提供的日志的配置参数

  1. # ----------------------------------------
  2. # CORE PROPERTIES
  3. # ----------------------------------------
  4. debug=false # Enable debug logs.
  5. trace=false # Enable trace logs.
  6. LOGGING

  7. logging.config= # Location of the logging configuration file. For instance, classpath:logback.xml for Logback.

  8. logging.exception-conversion-word=%wEx # Conversion word used when logging exceptions.

  9. logging.file= # Log file name (for instance, myapp.log). Names can be an exact location or relative to the current directory.

  10. logging.file.max-history=0 # Maximum of archive log files to keep. Only supported with the default logback setup.

  11. logging.file.max-size=10MB # Maximum log file size. Only supported with the default logback setup.

  12. logging.group.= # Log groups to quickly change multiple loggers at the same time. For instance, logging.level.db=org.hibernate,org.springframework.jdbc.

  13. logging.level.= # Log levels severity mapping. For instance, logging.level.org.springframework=DEBUG.

  14. logging.path= # Location of the log file. For instance, /var/log.

  15. logging.pattern.console= # Appender pattern for output to the console. Supported only with the default Logback setup.

  16. logging.pattern.dateformat=yyyy-MM-dd HH:mm:ss.SSS # Appender pattern for log date format. Supported only with the default Logback setup.

  17. logging.pattern.file= # Appender pattern for output to a file. Supported only with the default Logback setup.

  18. logging.pattern.level=%5p # Appender pattern for log level. Supported only with the default Logback setup.

  19. logging.register-shutdown-hook=false # Register a shutdown hook for the logging system when it is initialized.

通常只需要在applicatiom.yml中配置即可,但是如果想要对日志进行更加复杂纤细的配置,可能就需要使用到对应日志系统的配置文件了。如果使用logbak,我们只需要在resource中添加logback.xml文件即可(当然下面只是简单实例,详细的logbak的xml配置请读者自行配置):

  1. <?xml version="1.0" encoding="GBK"?>
  2. <configuration debug="false">
  3. <appender name="CONSOLE"
  4. class="ch.qos.logback.core.ConsoleAppender">
  5. <encoder>
  6. <charset>UTF-8</charset>
  7. <pattern>
  8. %d %-4relative [%thread] %-5level %logger{36} [T:%X{trans}] - %msg%n
  9. </pattern>
  10. </encoder>
  11. </appender>
  12. <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
  13. <file>logs/demo.log</file>
  14. <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
  15. <fileNamePattern>logs/demo.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
  16. <maxHistory>10</maxHistory>
  17. <maxFileSize>200MB</maxFileSize>
  18. <totalSizeCap>10GB</totalSizeCap>
  19. </rollingPolicy>
  20. <encoder>
  21. <pattern>[%d{yyyy-MM-dd HH:mm:ss}] [%thread] %level %logger{35} [T:%X{trans}] %msg%n</pattern>
  22. </encoder>
  23. </appender>
  24. <span class="token tag"><span class="token tag"><span class="token punctuation"><span class="hljs-tag"><span class="hljs-tag"><span class="hljs-tag"><span class="hljs-tag">&lt;</span></span></span></span></span><span class="hljs-tag"><span class="hljs-name"><span class="hljs-tag"><span class="hljs-name"><span class="hljs-tag"><span class="hljs-name"><span class="hljs-tag"><span class="hljs-name">root</span></span></span></span></span></span></span></span></span><span class="hljs-tag"><span class="hljs-tag"><span class="hljs-tag"><span class="hljs-tag"> </span></span></span></span><span class="token attr-name"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr">level</span></span></span></span></span></span></span></span></span><span class="token attr-value"><span class="token punctuation"><span class="hljs-tag"><span class="hljs-tag"><span class="hljs-tag"><span class="hljs-tag">=</span></span></span></span></span><span class="token punctuation"><span class="hljs-tag"><span class="hljs-string"><span class="hljs-tag"><span class="hljs-string"><span class="hljs-tag"><span class="hljs-string"><span class="hljs-tag"><span class="hljs-string">"</span></span></span></span></span></span></span></span></span><span class="hljs-tag"><span class="hljs-string"><span class="hljs-tag"><span class="hljs-string"><span class="hljs-tag"><span class="hljs-string"><span class="hljs-tag"><span class="hljs-string">INFO</span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-tag"><span class="hljs-string"><span class="hljs-tag"><span class="hljs-string"><span class="hljs-tag"><span class="hljs-string"><span class="hljs-tag"><span class="hljs-string">"</span></span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-tag"><span class="hljs-tag"><span class="hljs-tag"><span class="hljs-tag">&gt;</span></span></span></span></span></span>
  25.     <span class="token tag"><span class="token tag"><span class="token punctuation"><span class="hljs-tag"><span class="hljs-tag"><span class="hljs-tag"><span class="hljs-tag">&lt;</span></span></span></span></span><span class="hljs-tag"><span class="hljs-name"><span class="hljs-tag"><span class="hljs-name"><span class="hljs-tag"><span class="hljs-name"><span class="hljs-tag"><span class="hljs-name">appender-ref</span></span></span></span></span></span></span></span></span><span class="hljs-tag"><span class="hljs-tag"><span class="hljs-tag"><span class="hljs-tag"> </span></span></span></span><span class="token attr-name"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr">ref</span></span></span></span></span></span></span></span></span><span class="token attr-value"><span class="token punctuation"><span class="hljs-tag"><span class="hljs-tag"><span class="hljs-tag"><span class="hljs-tag">=</span></span></span></span></span><span class="token punctuation"><span class="hljs-tag"><span class="hljs-string"><span class="hljs-tag"><span class="hljs-string"><span class="hljs-tag"><span class="hljs-string"><span class="hljs-tag"><span class="hljs-string">"</span></span></span></span></span></span></span></span></span><span class="hljs-tag"><span class="hljs-string"><span class="hljs-tag"><span class="hljs-string"><span class="hljs-tag"><span class="hljs-string"><span class="hljs-tag"><span class="hljs-string">FILE</span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-tag"><span class="hljs-string"><span class="hljs-tag"><span class="hljs-string"><span class="hljs-tag"><span class="hljs-string"><span class="hljs-tag"><span class="hljs-string">"</span></span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-tag"><span class="hljs-tag"><span class="hljs-tag"><span class="hljs-tag">/&gt;</span></span></span></span></span></span>
  26.     <span class="token tag"><span class="token tag"><span class="token punctuation"><span class="hljs-tag"><span class="hljs-tag"><span class="hljs-tag"><span class="hljs-tag">&lt;</span></span></span></span></span><span class="hljs-tag"><span class="hljs-name"><span class="hljs-tag"><span class="hljs-name"><span class="hljs-tag"><span class="hljs-name"><span class="hljs-tag"><span class="hljs-name">appender-ref</span></span></span></span></span></span></span></span></span><span class="hljs-tag"><span class="hljs-tag"><span class="hljs-tag"><span class="hljs-tag"> </span></span></span></span><span class="token attr-name"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr">ref</span></span></span></span></span></span></span></span></span><span class="token attr-value"><span class="token punctuation"><span class="hljs-tag"><span class="hljs-tag"><span class="hljs-tag"><span class="hljs-tag">=</span></span></span></span></span><span class="token punctuation"><span class="hljs-tag"><span class="hljs-string"><span class="hljs-tag"><span class="hljs-string"><span class="hljs-tag"><span class="hljs-string"><span class="hljs-tag"><span class="hljs-string">"</span></span></span></span></span></span></span></span></span><span class="hljs-tag"><span class="hljs-string"><span class="hljs-tag"><span class="hljs-string"><span class="hljs-tag"><span class="hljs-string"><span class="hljs-tag"><span class="hljs-string">CONSOLE</span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-tag"><span class="hljs-string"><span class="hljs-tag"><span class="hljs-string"><span class="hljs-tag"><span class="hljs-string"><span class="hljs-tag"><span class="hljs-string">"</span></span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-tag"><span class="hljs-tag"><span class="hljs-tag"><span class="hljs-tag">/&gt;</span></span></span></span></span></span>
  27. <span class="token tag"><span class="token tag"><span class="token punctuation"><span class="hljs-tag"><span class="hljs-tag"><span class="hljs-tag"><span class="hljs-tag">&lt;/</span></span></span></span></span><span class="hljs-tag"><span class="hljs-name"><span class="hljs-tag"><span class="hljs-name"><span class="hljs-tag"><span class="hljs-name"><span class="hljs-tag"><span class="hljs-name">root</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-tag"><span class="hljs-tag"><span class="hljs-tag"><span class="hljs-tag">&gt;</span></span></span></span></span></span>
  28. </configuration>

@Slf4j

为了方便的使用日志,可以借助spring的@slf4j注解,可以自动注入log,代码中可以直接使用,比较方便:

  1. @RestController
  2. @Slf4j
  3. public class HelloController {
  4. @Autowired
  5. private Stu stu;
  6. @Autowired
  7. private Person person;
  8. <span class="token annotation punctuation"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta">@GetMapping</span></span></span></span></span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"/properties1"</span></span></span></span></span><span class="token punctuation">)</span>
  9. <span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">public</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> String </span></span></span></span><span class="token function"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">properties1</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">(</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">)</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token punctuation">{</span>
  10.     log<span class="token punctuation">.</span><span class="token function">debug</span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"com.example.controller.HelloController.properties1 执行"</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  11.     log<span class="token punctuation">.</span><span class="token function">info</span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"stu={}"</span></span></span></span></span><span class="token punctuation">,</span> stu<span class="token punctuation">)</span><span class="token punctuation">;</span>
  12.     log<span class="token punctuation">.</span><span class="token function">info</span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"person={}"</span></span></span></span></span><span class="token punctuation">,</span> person<span class="token punctuation">)</span><span class="token punctuation">;</span>
  13.     <span class="token keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword">return</span></span></span></span></span> <span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"Welcome to springboot2 world ~"</span></span></span></span></span><span class="token punctuation">;</span>
  14. <span class="token punctuation">}</span>
  15. <span class="token comment"><span class="hljs-comment"><span class="hljs-comment"><span class="hljs-comment"><span class="hljs-comment">//省略代码</span></span></span></span></span>

单元测试

一个Spring Boot application 是Spring ApplicationContext, 在单元测试时没有什么特殊的。

当你使用SpringApplication 时,外部属性,日志等其他功能会被默认装配

springboot提供了@SpringBootTest注解来辅助我们进行测试。

需要注意:如果我们使用的是JUnit 4 ,那么需要添加@RunWith(SpringRunner.class)否则所有注解将会被忽略。

如果你使用的是JUnit5 ,那么在 SpringBootTest 上没有必要添加 @ExtendWith,因为@…Test已经添加了ExtendWith

  1. If you are using JUnit 4, dont forget to also add @RunWith(SpringRunner.class) to your test, otherwise the annotations will be
  2. ignored. If you are using JUnit 5, theres no need to add the equivalent @ExtendWith(SpringExtension) as @SpringBootTest and the
  3. other @…Test annotations are already annotated with it.

简单实例

引入test的starter依赖

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-test</artifactId>
  4. <scope>test</scope>
  5. </dependency>

在src/test/java目录下创建MyTest.java


  1. @RunWith(SpringRunner.class)
  2. @SpringBootTest(classes = {Application.class})// 指定启动类
  3. @Slf4j
  4. public class MyTests {
  5. @Autowired
  6. private Person person;
  7. @Autowired
  8. private HelloService helloService;
  9. <span class="token comment"><span class="hljs-comment"><span class="hljs-comment"><span class="hljs-comment"><span class="hljs-comment">/**
  10.  * 使用断言
  11.  */</span></span></span></span></span>
  12. <span class="token annotation punctuation"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta">@Test</span></span></span></span></span>
  13. <span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">public</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">void</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token function"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">test2</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">(</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">)</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token punctuation">{</span>
  14.     log<span class="token punctuation">.</span><span class="token function">info</span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"test hello 2"</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  15.     TestCase<span class="token punctuation">.</span><span class="token function">assertEquals</span><span class="token punctuation">(</span><span class="token number"><span class="hljs-number"><span class="hljs-number"><span class="hljs-number"><span class="hljs-number">1</span></span></span></span></span><span class="token punctuation">,</span> <span class="token number"><span class="hljs-number"><span class="hljs-number"><span class="hljs-number"><span class="hljs-number">1</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  16. <span class="token punctuation">}</span>
  17. <span class="token comment"><span class="hljs-comment"><span class="hljs-comment"><span class="hljs-comment"><span class="hljs-comment">/**
  18.  * 测试注入
  19.  */</span></span></span></span></span>
  20. <span class="token annotation punctuation"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta">@Test</span></span></span></span></span>
  21. <span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">public</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">void</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token function"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">test3</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">(</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">)</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token punctuation">{</span>
  22.     log<span class="token punctuation">.</span><span class="token function">info</span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"person={}"</span></span></span></span></span><span class="token punctuation">,</span> person<span class="token punctuation">)</span><span class="token punctuation">;</span>
  23.     log<span class="token punctuation">.</span><span class="token function">info</span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"helloService.getVal()={}"</span></span></span></span></span><span class="token punctuation">,</span> helloService<span class="token punctuation">.</span><span class="token function">getVal</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  24. <span class="token punctuation">}</span>
  25. <span class="token annotation punctuation"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta">@Before</span></span></span></span></span>
  26. <span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">public</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">void</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token function"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">testBefore</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">(</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">)</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token punctuation">{</span>
  27.     System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"before"</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  28. <span class="token punctuation">}</span>
  29. <span class="token annotation punctuation"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta">@After</span></span></span></span></span>
  30. <span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">public</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">void</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token function"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">testAfter</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">(</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">)</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token punctuation">{</span>
  31.     System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"after"</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  32. <span class="token punctuation">}</span>
  33. }

我们这里单独执行test3,他会向正常启动springboot服务一样,注入相关的bean,输出如下:

@TestConfiguration

@TestConfiguration是Spring Boot Test提供的一种工具,用它我们可以在一般的@Configuration之外补充测试专门用的Bean或者自定义的配置。

我们看@TestConfiguration的定义

  1. @Target(ElementType.TYPE)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Documented
  4. @Configuration
  5. @TestComponent
  6. public @interface TestConfiguration {
  7. //省略

可见真正起作用的是@TestComponent:

  1. @Target(ElementType.TYPE)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Documented
  4. @Component
  5. public @interface TestComponent {
  6. //省略

@TestComponent 用于声明专门用于测试的bean , 他不应该被自动扫描到。也就是说如果你使用@ComponentScan来扫描bean,那么需要将其排除在外:

  1. @ComponentScan(excludeFilters = {
  2. @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
  3. ...})

由于@SpringBootApplication已经添加有排除TypeExcludeFilter的功能,固使用@SpringBootApplication时不会加载@TestComponent声明的bean:

  1. @Target(ElementType.TYPE)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Documented
  4. @Inherited
  5. @SpringBootConfiguration
  6. @EnableAutoConfiguration
  7. @ComponentScan(excludeFilters = {
  8. @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
  9. @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
  10. public @interface SpringBootApplication {

@TestConfiguration 应用实例

编写一个bean的创建类:

  1. package config;
  2. import com.example.pojo.Foo;

  3. import org.springframework.boot.test.context.TestConfiguration;

  4. import org.springframework.context.annotation.Bean;
  5. @TestConfiguration

  6. public class Config {
  7. <span class="token annotation punctuation"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta">@Bean</span></span></span></span></span>
  8. <span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">public</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> Foo </span></span></span></span><span class="token function"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">foo</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">(</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">)</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token punctuation">{</span>
  9.     <span class="token keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword">return</span></span></span></span></span> <span class="token keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword">new</span></span></span></span></span> <span class="token class-name">Foo</span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"from config"</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  10. <span class="token punctuation">}</span>
  11. }

Foo.java:

  1. @Data
  2. @AllArgsConstructor
  3. @NoArgsConstructor
  4. public class Foo {
  5. private String name;
  6. }

编写测试类(IDEA 可能会在foo属性上标红提示错误,不用管,IDE还没有那么智能,识别不了这里的自动注入):

  1. @RunWith(SpringRunner.class)
  2. @SpringBootTest(classes = {Application.class})// 指定启动类
  3. @Import(Config.class)
  4. @Slf4j
  5. public class TestConfiguration1 {
  6. <span class="token annotation punctuation"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta">@Autowired</span></span></span></span></span>
  7. <span class="token keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword">private</span></span></span></span></span> Foo foo<span class="token punctuation">;</span>
  8. <span class="token annotation punctuation"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta">@Test</span></span></span></span></span>
  9. <span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">public</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">void</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token function"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">testPlusCount</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">(</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">)</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token punctuation">{</span>
  10.     log<span class="token punctuation">.</span><span class="token function">info</span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"TestConfiguration1"</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  11.     Assert<span class="token punctuation">.</span><span class="token function">assertEquals</span><span class="token punctuation">(</span>foo<span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"from config"</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  12. <span class="token punctuation">}</span>
  13. }

执行这里的testPlusCount方法,测试通过。

当然上面Config中的注解@TestConfiguration可以换成@Configuration效果也是一样的,@TestConfiguration是专门用于测试的。

使用mock方式对controller进行单元测试(无需运行web服务)

默认情况下,使用@SpringBootTest不会真正启动web服务,当我们测试controller时,spring测试提供了MockMvc供我们方便的测试controller,就像从浏览器发起请求一样。

在HelloController中有这么一个方法:

  1. @GetMapping("/hello")
  2. public String hello() {
  3. return "Welcome to springboot2 world ~";
  4. }

启动服务在浏览器中访问:

关闭tomcat服务,我们看如何进行单元测试。

  1. import com.example.Application;
  2. import org.junit.Test;
  3. import org.junit.runner.RunWith;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
  6. import org.springframework.boot.test.context.SpringBootTest;
  7. import org.springframework.test.context.junit4.SpringRunner;
  8. import org.springframework.test.web.servlet.MockMvc;
  9. import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;

  10. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;

  11. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
  12. @RunWith(SpringRunner.class)

  13. @SpringBootTest(classes = {Application.class})// 指定启动类

  14. @AutoConfigureMockMvc

  15. public class MockMvcExampleTests {

  16. @Autowired

  17. private MockMvc mvc;
  18. <span class="token annotation punctuation"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta">@Test</span></span></span></span></span>
  19. <span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">public</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">void</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token function"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">exampleTest</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">(</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">)</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">throws</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> Exception </span></span></span></span><span class="token punctuation">{</span>
  20.     <span class="token keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword">this</span></span></span></span></span><span class="token punctuation">.</span>mvc<span class="token punctuation">.</span><span class="token function">perform</span><span class="token punctuation">(</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"/hello"</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">andExpect</span><span class="token punctuation">(</span><span class="token function">status</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">isOk</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
  21.             <span class="token punctuation">.</span><span class="token function">andExpect</span><span class="token punctuation">(</span><span class="token function">content</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">string</span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"Welcome to springboot2 world ~"</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">)</span>
  22.             <span class="token punctuation">.</span><span class="token function">andDo</span><span class="token punctuation">(</span>MockMvcResultHandlers<span class="token punctuation">.</span><span class="token function">print</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  23. <span class="token punctuation">}</span>
  24. }

tomcat服务已经关闭,执行单元测试,输出结果:


  1. 2018-12-30 19:29:29.971 INFO 15100 --- [ main] MockMvcExampleTests : Starting MockMvcExampleTests on HIH-D-20265 with PID 15100 (started by hzliubenlong in D:\workspace-wy\springboot2demo)
  2. 2018-12-30 19:29:29.973 INFO 15100 --- [ main] MockMvcExampleTests : No active profile set, falling back to default profiles: default
  3. 2018-12-30 19:29:31.419 INFO 15100 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
  4. 2018-12-30 19:29:31.620 INFO 15100 --- [ main] o.s.b.t.m.w.SpringBootMockServletContext : Initializing Spring TestDispatcherServlet ''
  5. 2018-12-30 19:29:31.624 INFO 15100 --- [ main] o.s.t.web.servlet.TestDispatcherServlet : Initializing Servlet ''
  6. 2018-12-30 19:29:31.633 INFO 15100 --- [ main] o.s.t.web.servlet.TestDispatcherServlet : Completed initialization in 9 ms
  7. 2018-12-30 19:29:31.651 INFO 15100 --- [ main] MockMvcExampleTests : Started MockMvcExampleTests in 2.201 seconds (JVM running for 2.974)
  8. MockHttpServletRequest:

  9. HTTP Method = GET

  10. Request URI = /hello

  11. Parameters = {}

  12. Headers = {}

  13. Body = null

  14. Session Attrs = {}
  15. Handler:

  16. Type = com.example.controller.HelloController

  17. Method = public java.lang.String com.example.controller.HelloController.hello()
  18. Async:

  19. Async started = false

  20. Async result = null
  21. Resolved Exception:

  22. Type = null
  23. ModelAndView:

  24. View name = null

  25. View = null

  26. Model = null
  27. FlashMap:

  28. Attributes = null
  29. MockHttpServletResponse:

  30. Status = 200

  31. Error message = null

  32. Headers = {Content-Type=[text/plain;charset=UTF-8], Content-Length=[30]}

  33. Content type = text/plain;charset=UTF-8

  34. Body = Welcome to springboot2 world ~

  35. Forwarded URL = null

  36. Redirected URL = null

  37. Cookies = []

  38. 2018-12-30 19:29:31.916 INFO 15100 --- [ Thread-2] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'

其中中间的内容为打印的请求详细信息,该测试通过。

使用mock方式对controller进行单元测试(无需运行web服务)

如果您需要启动运行web服务,我们建议您使用随机端口。 如果您使用的是@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT),则可以随机进行测试运行。

这里允许自动注入TestRestTemplate:

  1. import com.example.Application;
  2. import org.junit.Test;
  3. import org.junit.runner.RunWith;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.boot.test.context.SpringBootTest;
  6. import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
  7. import org.springframework.boot.test.web.client.TestRestTemplate;
  8. import org.springframework.test.context.junit4.SpringRunner;
  9. import static org.assertj.core.api.Assertions.assertThat;
  10. /**
    • 测试基于普通springmvc的运行的controller服务

    • */

    • @RunWith(SpringRunner.class)

    • //使用随机端口

    • @SpringBootTest(classes = Application.class, webEnvironment = WebEnvironment.RANDOM_PORT)

    • public class RandomPortTestRestTemplateExampleTests {
    • @Autowired

    • private TestRestTemplate restTemplate;
    • @Test

    • public void exampleTest() {

    • String body = this.restTemplate.getForObject("/hello", String.class);

    • assertThat(body).isEqualTo("Welcome to springboot2 world ~");

    • }

    • }

首先启动该springboot应用,然后执行这个单元测试。

使用mock方式对controller进行单元测试(需运行web服务且 使用webflux)

具体的webflux相关的内容后续会讲。这里只需要知道这个springboot提供的是基于reactor的响应式编程(异步非阻塞)架构就行了。而我们之前使用的基于Tomcat的servlet3.1之前的springmvc是同步阻塞的。

要想使用webflux,需要更换spring-boot-starter-webspring-boot-starter-webflux

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-webflux</artifactId>
  4. </dependency>

编写测试代码

  1. import com.example.Application;
  2. import org.junit.Test;
  3. import org.junit.runner.RunWith;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.boot.test.context.SpringBootTest;
  6. import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
  7. import org.springframework.test.context.junit4.SpringRunner;
  8. import org.springframework.test.web.reactive.server.WebTestClient;
  9. @RunWith(SpringRunner.class)

  10. //指定使用随机端口(官网推荐的,原因待验证)

  11. @SpringBootTest(classes = Application.class, webEnvironment = WebEnvironment.RANDOM_PORT)

  12. public class RandomPortWebTestClientExampleTests {

  13. /**

  14. *WebTestClient 是用于测试web服务器的非阻塞的响应式客户端

  15. */

  16. @Autowired

  17. private WebTestClient webClient;
  18. <span class="token annotation punctuation"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta">@Test</span></span></span></span></span>
  19. <span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">public</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">void</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token function"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">exampleTest</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">(</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">)</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token punctuation">{</span>
  20.     <span class="token keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword">this</span></span></span></span></span><span class="token punctuation">.</span>webClient<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">uri</span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"/hello"</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">exchange</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">expectStatus</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">isOk</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  21.             <span class="token punctuation">.</span><span class="token function">expectBody</span><span class="token punctuation">(</span>String<span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">isEqualTo</span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"Welcome to springboot2 world ~"</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  22. <span class="token punctuation">}</span>
  23. }

首先启动该springboot应用,然后执行这个单元测试。

改为webflux的starter以后,观察启动日志,可以发现不再是基于Tomcat,而是基于netty了Netty started on port(s): 8080

@MockBean 对bean进行mock测试

在实际项目中,有一些bean可能会调用第三方,依赖外部组件或项目。但是我们单元测试不需要真正调用。那么我们可以使用@MockBean进行mock结果。

假设HelloService中有调用外部服务的方法:

  1. public interface HelloService {
  2. <span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function">String </span></span></span></span><span class="token function"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">getVal</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">(</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">)</span></span></span></span></span></span></span></span></span><span class="token punctuation">;</span>
  3. <span class="token comment"><span class="hljs-comment"><span class="hljs-comment"><span class="hljs-comment"><span class="hljs-comment">//模拟远程调用,或者其他服务调用</span></span></span></span></span>
  4. <span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function">String </span></span></span></span><span class="token function"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">getRemoteVal</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">(</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">)</span></span></span></span></span></span></span></span></span><span class="token punctuation">;</span>
  5. }

  6. @Component

  7. @Slf4j

  8. public class HelloServiceImpl implements HelloService{

  9. <span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">public</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> String </span></span></span></span><span class="token function"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">getVal</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">(</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">)</span></span></span></span></span></span></span></span></span><span class="token punctuation">{</span>
  10.     <span class="token keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword">return</span></span></span></span></span> <span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"haha"</span></span></span></span></span><span class="token punctuation">;</span>
  11. <span class="token punctuation">}</span>
  12. <span class="token comment"><span class="hljs-comment"><span class="hljs-comment"><span class="hljs-comment"><span class="hljs-comment">//模拟远程调用,或者其他服务调用</span></span></span></span></span>
  13. <span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">public</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> String </span></span></span></span><span class="token function"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">getRemoteVal</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">(</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">)</span></span></span></span></span></span></span></span></span><span class="token punctuation">{</span>
  14.     log<span class="token punctuation">.</span><span class="token function">info</span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"真正发起外部请求"</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  15.     <span class="token keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword">return</span></span></span></span></span> <span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"remote Val"</span></span></span></span></span><span class="token punctuation">;</span>
  16. <span class="token punctuation">}</span>
  17. }

编写单元测试代码:

  1. import com.example.Application;
  2. import com.example.service.HelloService;
  3. import org.junit.Test;
  4. import org.junit.runner.RunWith;
  5. import org.springframework.boot.test.context.SpringBootTest;
  6. import org.springframework.boot.test.mock.mockito.MockBean;
  7. import org.springframework.test.context.junit4.SpringRunner;
  8. import static org.assertj.core.api.Assertions.assertThat;

  9. import static org.mockito.BDDMockito.given;
  10. /**
    • 测试bean结果的mock

    • */

    • @RunWith(SpringRunner.class)

    • @SpringBootTest(classes = {Application.class})// 指定启动类

    • public class MockBeanTest {

    • @MockBean //这里使用 @SpyBean 是同样效果

    • private HelloService helloService;

    • @Test

    • public void exampleTest() {

    • //这句的意思是当调用helloService的getRemoteVal方法时,返回mock的结果:"远程调用结果"

    • given(this.helloService.getRemoteVal()).willReturn("远程调用结果");
    •  <span class="token comment"><span class="hljs-comment"><span class="hljs-comment"><span class="hljs-comment"><span class="hljs-comment">//进行调用测试</span></span></span></span></span>
    •  String reverse <span class="token operator">=</span> helloService<span class="token punctuation">.</span><span class="token function">getRemoteVal</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    •  <span class="token function">assertThat</span><span class="token punctuation">(</span>reverse<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">isEqualTo</span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"远程调用结果"</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    • }

    • }

执行单元测试,可以发现并没有真正发起请求。

更多测试相关内容请参见官网 Testing

测试json @JsonTest

  1. import static org.assertj.core.api.Assertions.assertThat;
  2. @RunWith(SpringRunner.class)

  3. //这里不能使用@SpringBootTest否则报错:Configuration error: found multiple declarations of @BootstrapWith for test class [MyJsonTests]

  4. @ContextConfiguration(classes = {Application.class})

  5. @JsonTest

  6. public class MyJsonTests extends AbstractTestNGSpringContextTests {
  7. <span class="token annotation punctuation"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta">@Autowired</span></span></span></span></span>
  8. <span class="token keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword">private</span></span></span></span></span> JacksonTester<span class="token generics function"><span class="token punctuation">&lt;</span>Stu<span class="token punctuation">&gt;</span></span> json<span class="token punctuation">;</span>
  9. <span class="token annotation punctuation"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta">@Test</span></span></span></span></span>
  10. <span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">public</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">void</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token function"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">testSerialize</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">(</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">)</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">throws</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> Exception </span></span></span></span><span class="token punctuation">{</span>
  11.     Stu details <span class="token operator">=</span> <span class="token keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword">new</span></span></span></span></span> <span class="token class-name">Stu</span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"马云"</span></span></span></span></span><span class="token punctuation">,</span> <span class="token number"><span class="hljs-number"><span class="hljs-number"><span class="hljs-number"><span class="hljs-number">51</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  12.     <span class="token comment"><span class="hljs-comment"><span class="hljs-comment"><span class="hljs-comment"><span class="hljs-comment">// Assert against a `.json` file in the same package as the test</span></span></span></span></span>
  13.     <span class="token function">assertThat</span><span class="token punctuation">(</span><span class="token keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword">this</span></span></span></span></span><span class="token punctuation">.</span>json<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span>details<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">isEqualToJson</span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"expected.json"</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  14.     <span class="token comment"><span class="hljs-comment"><span class="hljs-comment"><span class="hljs-comment"><span class="hljs-comment">// 或者使用基于JSON path的校验</span></span></span></span></span>
  15.     <span class="token function">assertThat</span><span class="token punctuation">(</span><span class="token keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword">this</span></span></span></span></span><span class="token punctuation">.</span>json<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span>details<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">hasJsonPathStringValue</span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"@.name"</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  16.     <span class="token function">assertThat</span><span class="token punctuation">(</span><span class="token keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword">this</span></span></span></span></span><span class="token punctuation">.</span>json<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span>details<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">extractingJsonPathStringValue</span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"@.name"</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">isEqualTo</span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"马云"</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  17. <span class="token punctuation">}</span>
  18. <span class="token annotation punctuation"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta">@Test</span></span></span></span></span>
  19. <span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">public</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">void</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token function"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">testDeserialize</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">(</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">)</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">throws</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> Exception </span></span></span></span><span class="token punctuation">{</span>
  20.     String content <span class="token operator">=</span> <span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"{\"name\":\"2\",\"age\":\"11\"}"</span></span></span></span></span><span class="token punctuation">;</span>
  21.     <span class="token function">assertThat</span><span class="token punctuation">(</span><span class="token keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword">this</span></span></span></span></span><span class="token punctuation">.</span>json<span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>content<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">isEqualTo</span><span class="token punctuation">(</span><span class="token keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword">new</span></span></span></span></span> <span class="token class-name">Stu</span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"2"</span></span></span></span></span><span class="token punctuation">,</span> <span class="token number"><span class="hljs-number"><span class="hljs-number"><span class="hljs-number"><span class="hljs-number">11</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  22.     <span class="token function">assertThat</span><span class="token punctuation">(</span><span class="token keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword">this</span></span></span></span></span><span class="token punctuation">.</span>json<span class="token punctuation">.</span><span class="token function">parseObject</span><span class="token punctuation">(</span>content<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">isEqualTo</span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"2"</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  23. <span class="token punctuation">}</span>
  24. }

这里不能使用@SpringBootTest否则报错:Configuration error: found multiple declarations of @BootstrapWith for test class [MyJsonTests]

有时候我们会自定义序列化风格,这里对@JsonComponent进行测试:

  1. @JsonComponent
  2. public class FooJsonComponent {
  3. <span class="token keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword">public</span></span></span></span></span> <span class="token keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword">static</span></span></span></span></span> <span class="token keyword"><span class="hljs-class"><span class="hljs-keyword"><span class="hljs-class"><span class="hljs-keyword"><span class="hljs-class"><span class="hljs-keyword"><span class="hljs-class"><span class="hljs-keyword">class</span></span></span></span></span></span></span></span></span><span class="hljs-class"><span class="hljs-class"><span class="hljs-class"><span class="hljs-class"> </span></span></span></span><span class="token class-name"><span class="hljs-class"><span class="hljs-title"><span class="hljs-class"><span class="hljs-title"><span class="hljs-class"><span class="hljs-title"><span class="hljs-class"><span class="hljs-title">Serializer</span></span></span></span></span></span></span></span></span><span class="hljs-class"><span class="hljs-class"><span class="hljs-class"><span class="hljs-class"> </span></span></span></span><span class="token keyword"><span class="hljs-class"><span class="hljs-keyword"><span class="hljs-class"><span class="hljs-keyword"><span class="hljs-class"><span class="hljs-keyword"><span class="hljs-class"><span class="hljs-keyword">extends</span></span></span></span></span></span></span></span></span><span class="hljs-class"><span class="hljs-class"><span class="hljs-class"><span class="hljs-class"> </span></span></span></span><span class="token class-name"><span class="hljs-class"><span class="hljs-title"><span class="hljs-class"><span class="hljs-title"><span class="hljs-class"><span class="hljs-title"><span class="hljs-class"><span class="hljs-title">JsonSerializer</span></span></span></span></span></span></span></span></span><span class="token generics function"><span class="token punctuation"><span class="hljs-class"><span class="hljs-class"><span class="hljs-class"><span class="hljs-class">&lt;</span></span></span></span></span><span class="hljs-class"><span class="hljs-title"><span class="hljs-class"><span class="hljs-title"><span class="hljs-class"><span class="hljs-title"><span class="hljs-class"><span class="hljs-title">Stu</span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-class"><span class="hljs-class"><span class="hljs-class"><span class="hljs-class">&gt;</span></span></span></span></span></span><span class="hljs-class"><span class="hljs-class"><span class="hljs-class"><span class="hljs-class"> </span></span></span></span><span class="token punctuation">{</span>
  4.     <span class="token annotation punctuation"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta">@Override</span></span></span></span></span>
  5.     <span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">public</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">void</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token function"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">serialize</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">(</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">Stu value</span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">,</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"> JsonGenerator gen</span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">,</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"> SerializerProvider serializers</span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">)</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function">
  6.             </span></span></span></span><span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">throws</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> IOException</span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function">,</span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> JsonProcessingException </span></span></span></span><span class="token punctuation">{</span>
  7.         gen<span class="token punctuation">.</span><span class="token function">writeString</span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"name="</span></span></span></span></span> <span class="token operator">+</span> value<span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">",age="</span></span></span></span></span> <span class="token operator">+</span> value<span class="token punctuation">.</span><span class="token function">getAge</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  8.     <span class="token punctuation">}</span>
  9. <span class="token punctuation">}</span>
  10. <span class="token keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword">public</span></span></span></span></span> <span class="token keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword">static</span></span></span></span></span> <span class="token keyword"><span class="hljs-class"><span class="hljs-keyword"><span class="hljs-class"><span class="hljs-keyword"><span class="hljs-class"><span class="hljs-keyword"><span class="hljs-class"><span class="hljs-keyword">class</span></span></span></span></span></span></span></span></span><span class="hljs-class"><span class="hljs-class"><span class="hljs-class"><span class="hljs-class"> </span></span></span></span><span class="token class-name"><span class="hljs-class"><span class="hljs-title"><span class="hljs-class"><span class="hljs-title"><span class="hljs-class"><span class="hljs-title"><span class="hljs-class"><span class="hljs-title">Deserializer</span></span></span></span></span></span></span></span></span><span class="hljs-class"><span class="hljs-class"><span class="hljs-class"><span class="hljs-class"> </span></span></span></span><span class="token keyword"><span class="hljs-class"><span class="hljs-keyword"><span class="hljs-class"><span class="hljs-keyword"><span class="hljs-class"><span class="hljs-keyword"><span class="hljs-class"><span class="hljs-keyword">extends</span></span></span></span></span></span></span></span></span><span class="hljs-class"><span class="hljs-class"><span class="hljs-class"><span class="hljs-class"> </span></span></span></span><span class="token class-name"><span class="hljs-class"><span class="hljs-title"><span class="hljs-class"><span class="hljs-title"><span class="hljs-class"><span class="hljs-title"><span class="hljs-class"><span class="hljs-title">JsonDeserializer</span></span></span></span></span></span></span></span></span><span class="token generics function"><span class="token punctuation"><span class="hljs-class"><span class="hljs-class"><span class="hljs-class"><span class="hljs-class">&lt;</span></span></span></span></span><span class="hljs-class"><span class="hljs-title"><span class="hljs-class"><span class="hljs-title"><span class="hljs-class"><span class="hljs-title"><span class="hljs-class"><span class="hljs-title">Stu</span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-class"><span class="hljs-class"><span class="hljs-class"><span class="hljs-class">&gt;</span></span></span></span></span></span><span class="hljs-class"><span class="hljs-class"><span class="hljs-class"><span class="hljs-class"> </span></span></span></span><span class="token punctuation">{</span>
  11.     <span class="token annotation punctuation"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta">@Override</span></span></span></span></span>
  12.     <span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">public</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> Stu </span></span></span></span><span class="token function"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">deserialize</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">(</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">JsonParser p</span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">,</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"> DeserializationContext ctxt</span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">)</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">throws</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> IOException</span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function">,</span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> JsonProcessingException </span></span></span></span><span class="token punctuation">{</span>
  13.         JsonToken t <span class="token operator">=</span> p<span class="token punctuation">.</span><span class="token function">getCurrentToken</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  14.         <span class="token keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword">if</span></span></span></span></span> <span class="token punctuation">(</span>t <span class="token operator">==</span> JsonToken<span class="token punctuation">.</span>VALUE_STRING<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  15.             String trim <span class="token operator">=</span> p<span class="token punctuation">.</span><span class="token function">getText</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">trim</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  16.             String<span class="token punctuation">[</span><span class="token punctuation">]</span> split <span class="token operator">=</span> trim<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">","</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  17.             Stu stu <span class="token operator">=</span> <span class="token keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword">new</span></span></span></span></span> <span class="token class-name">Stu</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  18.             stu<span class="token punctuation">.</span><span class="token function">setName</span><span class="token punctuation">(</span>split<span class="token punctuation">[</span><span class="token number"><span class="hljs-number"><span class="hljs-number"><span class="hljs-number"><span class="hljs-number">0</span></span></span></span></span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"="</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number"><span class="hljs-number"><span class="hljs-number"><span class="hljs-number"><span class="hljs-number">1</span></span></span></span></span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  19.             stu<span class="token punctuation">.</span><span class="token function">setAge</span><span class="token punctuation">(</span>Integer<span class="token punctuation">.</span><span class="token function">parseInt</span><span class="token punctuation">(</span>split<span class="token punctuation">[</span><span class="token number"><span class="hljs-number"><span class="hljs-number"><span class="hljs-number"><span class="hljs-number">1</span></span></span></span></span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"="</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number"><span class="hljs-number"><span class="hljs-number"><span class="hljs-number"><span class="hljs-number">1</span></span></span></span></span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  20.             <span class="token keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword">return</span></span></span></span></span> stu<span class="token punctuation">;</span>
  21.         <span class="token punctuation">}</span>
  22.         <span class="token keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword">return</span></span></span></span></span> <span class="token punctuation">(</span>Stu<span class="token punctuation">)</span> ctxt<span class="token punctuation">.</span><span class="token function">handleUnexpectedToken</span><span class="token punctuation">(</span><span class="token function">handledType</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> p<span class="token punctuation">)</span><span class="token punctuation">;</span>
  23.     <span class="token punctuation">}</span>
  24. <span class="token punctuation">}</span>
  25. }

  26. /**

    • 测试自定义的@JsonComponent

    • */

    • @ContextConfiguration(classes = {JsonComponentJacksonTest.class, FooJsonComponent.class})

    • @JsonTest

    • public class JsonComponentJacksonTest extends AbstractTestNGSpringContextTests {

    • @Autowired

    • private JacksonTester<Stu> json;

    • @Test

    • public void testSerialize() throws Exception {

    • Stu details = new Stu("zhangsan", 12);

    • assertThat(this.json.write(details).getJson()).isEqualTo(""name=zhangsan,age=12"");

    • }

    • @Test

    • public void testDeserialize() throws Exception {

    • String content = ""name=zhangsan,age=13"";

    • Stu actual = this.json.parseObject(content);

    • assertThat(actual).isEqualTo(new Stu("zhangsan", 13));

    • assertThat(actual.getName()).isEqualTo("zhangsan");

    • assertThat(actual.getAge()).isEqualTo(13);

    • }

    • }

@TestPropertySource 对属性配置进行mock

使用springboot我们通常会将配置设置在application.yml中,但是在测试的时候,可能会对某些配置的值进行修改,接下来我们使用@TestPropertySource来实现这个功能。

使用spring提供的@PropertySource

springboot提供的@ConfigurationProperties可以加载application.yml中的配置,如果你的配置放到其他目录或者叫其他名称,可以使用@PropertySource来进行加载。

我们在resources目录下创建两个配置文件:



property-source.properties文件内容是lastName=wanganshi。property-source.yml内容是lastName: libai@PropertySource可以支持properties和yml两种格式。

编写类PropertySourceConfig.java来加载配置文件中的内容

  1. import org.springframework.context.annotation.Configuration;
  2. import org.springframework.context.annotation.PropertySource;
  3. @Configuration

  4. //支持properties和yml

  5. //@PropertySource("classpath:property-source.properties")

  6. @PropertySource("classpath:property-source.yml")

  7. public class PropertySourceConfig {

  8. }

编写测试类:

  1. import lombok.extern.slf4j.Slf4j;
  2. import org.junit.Assert;
  3. import org.junit.Test;
  4. import org.junit.runner.RunWith;
  5. import org.springframework.boot.test.context.SpringBootTest;
  6. import org.springframework.context.EnvironmentAware;
  7. import org.springframework.core.env.ConfigurableEnvironment;
  8. import org.springframework.core.env.Environment;
  9. import org.springframework.test.context.ContextConfiguration;
  10. import org.springframework.test.context.TestPropertySource;
  11. import org.springframework.test.context.junit4.SpringRunner;
  12. import java.util.Map;
  13. import static java.util.stream.Collectors.toList;
  14. @RunWith(SpringRunner.class)

  15. @SpringBootTest

  16. @Slf4j

  17. @ContextConfiguration(classes = PropertySourceConfig.class) //加载属性配置

  18. @TestPropertySource( // 对属性进行设置

  19. properties = {"lastName=abc", "bar=uvw"}

  20. )

  21. public class PropertySourceTest1 implements EnvironmentAware {
  22. <span class="token keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword">private</span></span></span></span></span> Environment environment<span class="token punctuation">;</span>
  23. <span class="token annotation punctuation"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta">@Test</span></span></span></span></span>
  24. <span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">public</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">void</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token function"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">test1</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">(</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">)</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token punctuation">{</span>
  25.     Assert<span class="token punctuation">.</span><span class="token function">assertEquals</span><span class="token punctuation">(</span>environment<span class="token punctuation">.</span><span class="token function">getProperty</span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"lastName"</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"abc"</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  26. <span class="token punctuation">}</span>
  27. <span class="token annotation punctuation"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta">@Override</span></span></span></span></span>
  28. <span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">public</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">void</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token function"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">setEnvironment</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">(</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">Environment environment</span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">)</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token punctuation">{</span>
  29.     <span class="token keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword">this</span></span></span></span></span><span class="token punctuation">.</span>environment <span class="token operator">=</span> environment<span class="token punctuation">;</span>
  30.     Map<span class="token generics function"><span class="token punctuation">&lt;</span>String<span class="token punctuation">,</span> Object<span class="token punctuation">&gt;</span></span> systemEnvironment <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>ConfigurableEnvironment<span class="token punctuation">)</span> environment<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getSystemEnvironment</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  31.     System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"=== System Environment ==="</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  32.     System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token function">getMapString</span><span class="token punctuation">(</span>systemEnvironment<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  33.     System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  34.     System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"=== Java System Properties ==="</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  35.     Map<span class="token generics function"><span class="token punctuation">&lt;</span>String<span class="token punctuation">,</span> Object<span class="token punctuation">&gt;</span></span> systemProperties <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>ConfigurableEnvironment<span class="token punctuation">)</span> environment<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getSystemProperties</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  36.     System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token function">getMapString</span><span class="token punctuation">(</span>systemProperties<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  37. <span class="token punctuation">}</span>
  38. <span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">private</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> String </span></span></span></span><span class="token function"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">getMapString</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">(</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">Map</span></span></span></span></span></span></span></span><span class="token generics function"><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">&lt;</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">String</span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">,</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"> Object</span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">&gt;</span></span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"> map</span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">)</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token punctuation">{</span>
  39.     <span class="token keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword">return</span></span></span></span></span> String<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"\n"</span></span></span></span></span><span class="token punctuation">,</span>
  40.             map<span class="token punctuation">.</span><span class="token function">keySet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">stream</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>k <span class="token operator">-</span><span class="token operator">&gt;</span> k <span class="token operator">+</span> <span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"="</span></span></span></span></span> <span class="token operator">+</span> map<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>k<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">collect</span><span class="token punctuation">(</span><span class="token function">toList</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
  41.     <span class="token punctuation">)</span><span class="token punctuation">;</span>
  42. <span class="token punctuation">}</span>
  43. }

测试通过。大家可以将@TestPropertySource注解去掉来观察输出结果。

对springboot提供的类型安全的属性配置进行mock

前面已经讲过如何进行类型安全的属性配置。这种情况依然可以使用@TestPropertySource对属性进行mock:

我们使用spring boot 2.1学习笔记【四】属性配置的Person类进行测试。

直接编写测试类:

  1. import com.example.Application;
  2. import com.example.pojo.Person;
  3. import lombok.extern.slf4j.Slf4j;
  4. import org.junit.Assert;
  5. import org.junit.Test;
  6. import org.junit.runner.RunWith;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.boot.test.context.SpringBootTest;
  9. import org.springframework.test.context.TestPropertySource;
  10. import org.springframework.test.context.junit4.SpringRunner;
  11. @RunWith(SpringRunner.class)

  12. @SpringBootTest(classes = {Application.class})// 指定启动类

  13. @Slf4j

  14. @TestPropertySource(

  15. properties = {"person.lastName=张飞", "person.age=49"}

  16. )

  17. public class PropertySourceTest {

  18. @Autowired

  19. private Person person;
  20. <span class="token annotation punctuation"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta">@Test</span></span></span></span></span>
  21. <span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">public</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">void</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token function"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">test1</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">(</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">)</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token punctuation">{</span>
  22.     log<span class="token punctuation">.</span><span class="token function">info</span><span class="token punctuation">(</span>person<span class="token punctuation">.</span><span class="token function">getLastName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  23.     Assert<span class="token punctuation">.</span><span class="token function">assertEquals</span><span class="token punctuation">(</span>person<span class="token punctuation">.</span><span class="token function">getLastName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"张飞"</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  24. <span class="token punctuation">}</span>
  25. }

测试结果通过,大家可以将@TestPropertySource注解去电观察运行结果。

为单元测试单独提供测试配置

就像上图中那样,我们在src/test/resources目录下创建一个单元测试专用的属性配置文件。就可以在@TestPropertySource指定加载这个配置即可。

test-property-source.yml文件内容:

  1. testp: 123456789
  2. person:
  3. lastName: abc

PropertySourceTest1进行改造:

  1. @RunWith(SpringRunner.class)
  2. @SpringBootTest
  3. @Slf4j
  4. @ContextConfiguration(classes = PropertySourceConfig.class) //加载属性配置
  5. @TestPropertySource( // 对属性进行设置
  6. properties = {"bar=uvw"},
  7. locations = "classpath:test-property-source.yml"
  8. )
  9. public class PropertySourceTest1 implements EnvironmentAware {
  10. <span class="token keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword">private</span></span></span></span></span> Environment environment<span class="token punctuation">;</span>
  11. <span class="token annotation punctuation"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta">@Value</span></span></span></span></span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"${testp}"</span></span></span></span></span><span class="token punctuation">)</span>
  12. String testp<span class="token punctuation">;</span>
  13. <span class="token annotation punctuation"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta">@Test</span></span></span></span></span>
  14. <span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">public</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">void</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token function"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">test1</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">(</span></span></span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">)</span></span></span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span></span><span class="token punctuation">{</span>
  15.     Assert<span class="token punctuation">.</span><span class="token function">assertEquals</span><span class="token punctuation">(</span>environment<span class="token punctuation">.</span><span class="token function">getProperty</span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"lastName"</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"abc"</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  16.     Assert<span class="token punctuation">.</span><span class="token function">assertEquals</span><span class="token punctuation">(</span>testp<span class="token punctuation">,</span> <span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"123456789"</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  17. <span class="token punctuation">}</span>
  18. <span class="token comment"><span class="hljs-comment"><span class="hljs-comment"><span class="hljs-comment"><span class="hljs-comment">//省略部分代码</span></span></span></span></span>
  19. }

对AOP进行测试

我们这里对HelloService使用AspectJ进行AOP代理:

  1. /**
  2. * AOP
  3. */
  4. @Component
  5. @Aspect
  6. public class HelloAspect {
  7. @Pointcut("execution(* com.example.service.HelloService.getVal())")
  8. public void pointcut() {
  9. }
  10. @Around("pointcut()")
  11. public String changeGetVal(ProceedingJoinPoint pjp) {
  12. return "aopResult";//简单起见,这里直接模拟一个返回值了
  13. }
  14. }

使用springboot进行配置,启用AOP

  1. @Configuration
  2. @EnableAspectJAutoProxy(proxyTargetClass = true)//启用aop
  3. @ComponentScan("com.example.service")
  4. public class AopConfig {
  5. }

我们队MockMvcExampleTests添加一个测试方法,验证一下结果:

  1. @Test
  2. public void exampleTest1() throws Exception {
  3. this.mvc.perform(get("/hello1")).andExpect(status().isOk())
  4. .andExpect(content().string("aopResult"))
  5. .andDo(MockMvcResultHandlers.print());
  6. }

测试通过,说明代理成功。接下来我们通过另一种方式直接对AOP进行测试,注释已经在代码中写清楚了:

  1. //省略部分import
  2. import static org.mockito.Matchers.any;
  3. import static org.mockito.Mockito.times;
  4. import static org.mockito.Mockito.verify;
  5. import static org.testng.Assert.*;
  6. /**
    • AOP测试

    • */

    • @RunWith(SpringRunner.class)

    • @SpringBootTest(classes = {Application.class})// 指定启动类

    • @TestExecutionListeners(listeners = MockitoTestExecutionListener.class)//开启Mockito的支持

    • @Slf4j

    • public class SpringBootAopTest extends AbstractTestNGSpringContextTests {
    • @SpyBean

    • private HelloAspect helloAspect;
    • @Autowired

    • private HelloService helloService;
    • @Test

    • public void testFooService() {

    • //判断helloService对象是不是HelloServiceImpl

    • assertNotEquals(helloService.getClass(), HelloServiceImpl.class);
    •  <span class="token comment"><span class="hljs-comment"><span class="hljs-comment"><span class="hljs-comment"><span class="hljs-comment">//接下来通过AopUtils、AopProxyUtils、AopTestUtils来判断helloService是否是代理的对象</span></span></span></span></span>
    •  <span class="token function">assertTrue</span><span class="token punctuation">(</span>AopUtils<span class="token punctuation">.</span><span class="token function">isAopProxy</span><span class="token punctuation">(</span>helloService<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    •  <span class="token function">assertTrue</span><span class="token punctuation">(</span>AopUtils<span class="token punctuation">.</span><span class="token function">isCglibProxy</span><span class="token punctuation">(</span>helloService<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    •  <span class="token function">assertEquals</span><span class="token punctuation">(</span>AopProxyUtils<span class="token punctuation">.</span><span class="token function">ultimateTargetClass</span><span class="token punctuation">(</span>helloService<span class="token punctuation">)</span><span class="token punctuation">,</span> HelloServiceImpl<span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    •  <span class="token function">assertEquals</span><span class="token punctuation">(</span>AopTestUtils<span class="token punctuation">.</span><span class="token function">getTargetObject</span><span class="token punctuation">(</span>helloService<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getClass</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> HelloServiceImpl<span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    •  <span class="token function">assertEquals</span><span class="token punctuation">(</span>AopTestUtils<span class="token punctuation">.</span><span class="token function">getUltimateTargetObject</span><span class="token punctuation">(</span>helloService<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getClass</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> HelloServiceImpl<span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    •  <span class="token comment"><span class="hljs-comment"><span class="hljs-comment"><span class="hljs-comment"><span class="hljs-comment">/**
    •   * 但是证明HelloServiceImpl Bean被代理并不意味着HelloAspect生效了(假设此时有多个</span></span></span><span class="hljs-doctag"><span class="hljs-comment"><span class="hljs-doctag"><span class="hljs-comment"><span class="hljs-doctag"><span class="hljs-comment"><span class="hljs-doctag">@Aspect</span></span></span></span></span></span></span><span class="hljs-comment"><span class="hljs-comment"><span class="hljs-comment">),
    •   * 那么我们还需要验证HelloServiceImpl.getVal的行为。
    •   * 这里调用两次:
    •   */</span></span></span></span></span>
    •  <span class="token function">assertEquals</span><span class="token punctuation">(</span>helloService<span class="token punctuation">.</span><span class="token function">getVal</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"aopResult"</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    •  <span class="token function">assertEquals</span><span class="token punctuation">(</span>helloService<span class="token punctuation">.</span><span class="token function">getVal</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"aopResult"</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    •  <span class="token comment"><span class="hljs-comment"><span class="hljs-comment"><span class="hljs-comment"><span class="hljs-comment">//通过MockitoTestExecutionListener来监听是否是调用了两次helloService.getVal()方法</span></span></span></span></span>
    •  <span class="token comment"><span class="hljs-comment"><span class="hljs-comment"><span class="hljs-comment"><span class="hljs-comment">//注意这一行代码测试的是helloAspect的行为,而不是helloService的行为</span></span></span></span></span>
    •  <span class="token function">verify</span><span class="token punctuation">(</span>helloAspect<span class="token punctuation">,</span> <span class="token function">times</span><span class="token punctuation">(</span><span class="token number"><span class="hljs-number"><span class="hljs-number"><span class="hljs-number"><span class="hljs-number">2</span></span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">changeGetVal</span><span class="token punctuation">(</span><span class="token function">any</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    • }

    • }

测试结果是通过。

springboot系列学习笔记全部文章请移步值博主专栏**: spring boot 2.X/spring cloud Greenwich

由于是一系列文章,所以后面的文章可能会使用到前面文章的项目。springboot系列代码全部上传至GitHub:https://github.com/liubenlong/springboot2_demo

本系列环境:Java11;springboot 2.1.1.RELEASE;springcloud Greenwich.RELEASE;MySQL 8.0.5;

参考资料

官方文档

spring-test-examples

springboot(16)Spring Boot使用单元测试

  1. 原文地址:https://blog.csdn.net/liubenlong007/article/details/85398181 </div>

SpringBootTest单元测试及日志的更多相关文章

  1. SpringBootTest单元测试实战、SpringBoot测试进阶高级篇之MockMvc讲解

    1.@SpringBootTest单元测试实战 简介:讲解SpringBoot的单元测试 1.引入相关依赖 <!--springboot程序测试依赖,如果是自动创建项目默认添加--> &l ...

  2. 小D课堂 - 零基础入门SpringBoot2.X到实战_第4节 Springboot2.0单元测试进阶实战和自定义异常处理_17、SpringBootTest单元测试实战

    笔记 1.@SpringBootTest单元测试实战     简介:讲解SpringBoot的单元测试         1.引入相关依赖              <!--springboot程 ...

  3. 7.Android-压力测试、单元测试、日志猫使用

    1.压力测试monkey 通过cmd输入下面命令: adb shell monkey -p com.example.phonecall --ignore-crashes --ignore-timeou ...

  4. 【SpringBoot】单元测试进阶实战、自定义异常处理、t部署war项目到tomcat9和启动原理讲解

    ========================4.Springboot2.0单元测试进阶实战和自定义异常处理 ============================== 1.@SpringBoot ...

  5. Spring Boot 2.x零基础入门到高级实战教程

    一.零基础快速入门SpringBoot2.0 1.SpringBoot2.x课程全套介绍和高手系列知识点 简介:介绍SpringBoot2.x课程大纲章节 java基础,jdk环境,maven基础 2 ...

  6. [转]小D课堂 - 零基础入门SpringBoot2.X到实战_汇总

    原文地址:https://www.cnblogs.com/wangjunwei/p/11392825.html 第1节零基础快速入门SpringBoot2.0 小D课堂 - 零基础入门SpringBo ...

  7. 小D课堂 - 零基础入门SpringBoot2.X到实战_汇总

    第1节零基础快速入门SpringBoot2.0 小D课堂 - 零基础入门SpringBoot2.X到实战_第1节零基础快速入门SpringBoot2.0_1.SpringBoot2.x课程介绍和高手系 ...

  8. Android 开发命令行完全攻略

    作为命令行的爱好者,我想写这个主题已经有好一段时间了.除了显得很酷之外,命令行的使用能够提高我们的开发效率,因为相比通过鼠标点击一系列的菜单选项,使用键盘输入几个字符并点击 TAB 健显然会快很多. ...

  9. (转)使用CruiseControl+SVN+ANT实现持续集成之二

    1. 环境搭建 1.1. 下载及目录介绍 从官方站点http://cruisecontrol.sourceforge.net/download.html下载一份最新的 CC 压缩包,最新的版本号为2. ...

随机推荐

  1. SpringBoot框架(4)-- 类装配及Bean装配监听器

    1.普通方式装配类对象   (1)添加带有@Bean注解的方法  User.java(带@Component注解) package com.demo.boot.bootenable.beanDemo1 ...

  2. pyqt5-QAbstractScrollArea滚动条

    继承  QObject-->QWidget-->QFrame-->QAbstractScrollArea 是抽象类 import sys from PyQt5.QtWidgets i ...

  3. day02项目配置代码

    一.maven相互依赖结构 1.parent(pom)[父类]2.common(jar)[工具类]3.pojo(jar)[实体类] 依赖 common(jar)4.dao(jar)[CRUD] 依赖 ...

  4. vue父组件更新,子组件也更新的方法

    1.父组件 使用 Math.ramdom() 2.子组件获取 然后监听这个ramdom变化,处理子组件的更新

  5. [luogu]P1066 2^k进制数[数学][递推][高精度]

    [luogu]P1066 2^k进制数 题目描述 设r是个2^k 进制数,并满足以下条件: (1)r至少是个2位的2^k 进制数. (2)作为2^k 进制数,除最后一位外,r的每一位严格小于它右边相邻 ...

  6. django FBV +CBV 视图处理方式总结

    1.FBV(function base views) 在视图里使用函数处理请求. url:        re_path('fbv', views.fbv),        # url(r'^fbv' ...

  7. 「HNOI2016」矿区

    https://loj.ac/problem/2052 题解 平面图转对偶图.. 首先我们转的话需要给所有的平面标号,然后找到每条边看看他们隔开了哪两个平面. 做法就是对每个点维护它的所有排好序的出边 ...

  8. 高级软件测试技术(测试管理工具实践day2)

    今天在紧张的学习之余,我们小组选定了bugzilla,并且打算在今天晚上刚进行下载安装. 在安装bugzilla需要的软件有MySQL数据库软件,activeperl软件,bugzilla安装包,II ...

  9. whu 1581 Union of cubes

    题目链接: http://acm.whu.edu.cn/land/problem/detail?problem_id=1581 ------------------------------------ ...

  10. 架构-数据库访问-SQL语言进行连接数据库服务器:SQL语言进行连接数据库服务器

    ylbtech-架构-数据库访问-SQL语言进行连接数据库服务器:SQL语言进行连接数据库服务器 数据库和应用服务器的连接. 在基于三层构架的信息系统开发中,应用服务器要利用SQL语言进行连接数据库服 ...