前言

mac上idea快捷键,command+shift+T根据类生成快捷键。

对spring容器中的类做单元测试

在src/main下建立UserService类,对其进行单于测试,生产其单元测试类(使用command+shift+T快捷键),生成的test类在src/test下

@Service
public class UserService {public Integer addUser(String username){System.out.println("user dao adduser [username="+username+"]");if(username == null){return 0;}return 1;}
}

springboot启动类:

@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class,args);}
}

测试类:

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserServiceTest {@Autowiredprivate UserService userService;@Testpublic void addUser() throws Exception {Assert.assertEquals(Integer.valueOf(1),userService.addUser("zhihao.miao"));Assert.assertEquals(Integer.valueOf(0),userService.addUser(null));}}

盲点扫描

RunWith注解,SpringRunner类,SpringJUnit4ClassRunner类,SpringBootTest注解的解释。

When a class is annotated with @RunWith or extends a class annotated with @RunWith, JUnit will invoke the class it references to run the tests in that class instead of the runner built into JUnit. We added this feature late in development. While it seems powerful we expect the runner API to change as we learn how people really use it. Some of the classes that are currently internal will likely be refined and become public.
当一个类用@RunWith注释或继承一个用@RunWith注释的类时,JUnit将调用它所引用的类来运行该类中的测试而不是开发者去在junit内部去构建它。我们在开发过程中使用这个特性。
For example, suites in JUnit 4 are built using RunWith, and a custom runner named Suite:
比如说,suites使用RunWith注解构建,

@RunWith(Suite.class)
@SuiteClasses({ATest.class, BTest.class, CTest.class})
public class ABCSuite {
}

SpringRunner is an alias for the SpringJUnit4ClassRunner.
SpringRunnerSpringJUnit4ClassRunner的一个别名。
To use this class, simply annotate a JUnit 4 based test class with @RunWith(SpringRunner.class).
使用这个类,简单注解一个JUnit 4 依赖的测试@RunWith(SpringRunner.class).
If you would like to use the Spring TestContext Framework with a runner other than
this one, use org.springframework.test.context.junit4.rules.SpringClassRule
and org.springframework.test.context.junit4.rules.SpringMethodRule.
如果你想使用Spring测试上下文而不是使用这个,你可以使用org.springframework.test.context.junit4.rules.SpringClassRuleorg.springframework.test.context.junit4.rules.SpringMethodRule.

SpringJUnit4ClassRunner is a custom extension of JUnit’s
BlockJUnit4ClassRunner which provides functionality of the
Spring TestContext Framework to standard JUnit tests by means of the
TestContextManager and associated support classes and annotations.
SpringJUnit4ClassRunner是JUnit’s的BlockJUnit4ClassRunner类的一个常规扩展,提供了一些spring测试环境上下文去规范JUnit测试,意味着TestContextManager和支持相关的类和注解。
Annotation that can be specified on a test class that runs Spring Boot based tests.
Provides the following features over and above the regular Spring TestContext
Framework:
注解制定了一个测试类运行了Spring Boot环境。提供了以下一些特性:
Uses SpringBootContextLoader as the default ContextLoader when no specific ContextConfiguration#loader() @ContextConfiguration(loader=…) is defined.
当没有特定的ContextConfiguration#loader()(@ContextConfiguration(loader=…))被定义那么就是SpringBootContextLoader作为默认的ContextLoader。
Automatically searches for a SpringBootConfiguration @SpringBootConfiguration when nested @Configuration is not used, and no explicit #classes() classes are
specified.
自动搜索到SpringBootConfiguration注解的文件。
Allows custom Environment properties to be defined using the properties() properties attribute}.
允许自动注入Environment类读取配置文件。
Provides support for different #webEnvironment() webEnvironment modes,
including the ability to start a fully running container listening on a
WebEnvironment#DEFINED_PORT defined or WebEnvironment#RANDOM_PORT
random port.
提供一个webEnvironment环境,可以完整的允许一个web环境使用随机的端口或者自定义的端口。
Registers a org.springframework.boot.test.web.client.TestRestTemplate
TestRestTemplate bean for use in web tests that are using a fully running container.
注册了TestRestTemplate类可以去做接口调用。

springboot测试步骤
直接在测试类上面加上如下2个注解
@RunWith(SpringRunner.class)
@SpringBootTest
就能取到spring中的容器的实例,如果配置了@Autowired那么就自动将对象注入。

在测试环境中获取一个bean,在项目中新建User类,然后在测试模块进行测试
在src/main下新建一个实例User

@Component
public class User {
}

src/test下创建测试类测试:

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserTest {@Autowiredpublic ApplicationContext context;@Testpublic void testNotNull(){Assert.assertNotNull(context.getBean(User.class));}
}

只在测试环境有效的bean

在src/test下新建二个类,我们发现分别使用@TestComponent和@TestConfiguration二个注解修饰,这些类只在测试环境生效

@TestComponent
public class Cat {public void index(){System.out.println("cat index");}
}
    @TestConfigurationpublic class TestBeanConfiguration {@Beanpublic Runnable createRunnable(){return () -> System.out.println("=====createRunnable=======");}}

测试类:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {TestBeanConfiguration.class,Cat.class})
public class TestApplication {@Autowiredpublic ApplicationContext context;@Testpublic void testNotNull(){Runnable runnable = context.getBean(Runnable.class);runnable.run();System.out.println("--------");Cat cat = context.getBean(Cat.class);cat.index();}
}

需要在@SpringBootTest注解的参数classes中加入参数,表示将某些类纳入测试环境的容器中。

配置文件属性的读取

springboot会只会读取到src/test/resources下的配置,不会读到正式环境下的配置文件(跟以前1.4.*版本的不一样,以前是优先读取测试环境配置文件,然后读取正式环境的配置)

@RunWith(SpringRunner.class)
@SpringBootTest
public class EnvTest {@Autowiredpublic Environment environment;@Testpublic void testValue(){Assert.assertEquals("zhihao.miao",environment.getProperty("developer.name"));}
}

除了在配置文件中设置属性,测试环境加载一些配置信息的二种方式:
第一种是使用@SpringBootTest注解,注解参数properties指定其value值,第二种使用EnvironmentTestUtils.addEnvironment方法进行设置。
测试:

@RunWith(SpringRunner.class)
@SpringBootTest(properties = {"app.version=1.0"})
public class EnvTest2 {@Autowiredprivate ConfigurableEnvironment environment;@Beforepublic void init(){EnvironmentTestUtils.addEnvironment(environment,"app.admin.user=zhangsan");}@Testpublic void testApplication(){Assert.assertEquals("1.0",environment.getProperty("app.version"));Assert.assertEquals("zhangsan",environment.getProperty("app.admin.user"));}
}

Mock方式的测试

正式环境只是一个接口,并没有实现,也并没有纳入spring容器进行管理。

public interface UserDao {Integer createUser(String userName);
}

测试

@RunWith(SpringRunner.class)
public class UserDaoTest {//使用MockBean是因为此时容器中没有UserMapper这个对象@MockBeanpublic UserDao userDao;//使用BDDMockito对行为进行预测,@Beforepublic void init(){BDDMockito.given(userDao.createUser("admin")).willReturn(1);BDDMockito.given(userDao.createUser("")).willReturn(0);BDDMockito.given(userDao.createUser(null)).willThrow(NullPointerException.class);}@Test(expected=NullPointerException.class)public void testCreateUser() {Assert.assertEquals(Integer.valueOf(1),userDao.createUser("admin")) ;Assert.assertEquals(Integer.valueOf(0),userDao.createUser("")) ;Assert.assertEquals(Integer.valueOf(1),userDao.createUser(null)) ;}
}

对controller进行测试

第一种方式:

定义一个Controller,用作测试:

@RestController
public class UserController {private Logger logger = LoggerFactory.getLogger(getClass());@GetMapping("/user/home")public String home(){logger.info("user home");return "user home";}@GetMapping("/user/show")public String show(@RequestParam("id") String id){logger.info("book show");return "show"+id;}
}

使用浏览器访问

http://localhost:8080/user/home
http://localhost:8080/user/show?id=100

使用测试类测试
@RunWith(SpringRunner.class)
//指定web环境,随机端口
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class UserControllerTest {

//这个对象是运行在web环境的时候加载到spring容器中
@Autowired
private TestRestTemplate testRestTemplate;@Test
public void testHome(){String context = testRestTemplate.getForObject("/user/home",String.class);Assert.assertEquals("user home",context);
}@Test
public void testShow(){String context = testRestTemplate.getForObject("/user/show?id=100",String.class);Assert.assertEquals("show10",context);
}

}

第二种方式,使用@WebMvcTest注解

@RunWith(SpringRunner.class)
@WebMvcTest(controllers = UserController.class)
public class UserControllerTest2 {@Autowiredpublic MockMvc mockMvc;@Testpublic void testHome() throws Exception {mockMvc.perform(MockMvcRequestBuilders.get("/user/home")).andExpect(MockMvcResultMatchers.status().isOk());mockMvc.perform(MockMvcRequestBuilders.get("/user/home")).andExpect(MockMvcResultMatchers.status().isOk()).andExpect(MockMvcResultMatchers.content().string("user home"));}@Testpublic void testShow() throws Exception {mockMvc.perform(MockMvcRequestBuilders.get("/user/show").param("id", "400")).andExpect(MockMvcResultMatchers.status().isOk());mockMvc.perform(MockMvcRequestBuilders.get("/user/show").param("id", "400")).andExpect(MockMvcResultMatchers.status().isOk()).andExpect(MockMvcResultMatchers.content().string("show400"));}
}


@WebMvcTest 不需要运行在web环境下,但是,需要指定controllers,表示需要测试哪些controllers。
这种方式只测试controller,controller里面的一些依赖,需要你自己去mock
@WebMvcTest 不会加载整个spring容器。

第三种方式

使用@SpringBootTest()与@AutoConfigureMockMvc结合,@SpringBootTest使用@SpringBootTest加载测试的spring上下文环境,@AutoConfigureMockMvc自动配置MockMvc这个类,

/*** @SpringBootTest 不能和  @WebMvcTest 同时使用* 如果使用MockMvc对象的话,需要另外加上@AutoConfigureMockMvc注解*/
@RunWith(SpringRunner.class)
@SpringBootTest()
@AutoConfigureMockMvc
public class UserControllerTest3 {@Autowiredprivate MockMvc mvc;@Testpublic void testHome() throws Exception {mvc.perform(MockMvcRequestBuilders.get("/user/home")).andExpect(MockMvcResultMatchers.status().isOk());mvc.perform(MockMvcRequestBuilders.get("/user/home")).andExpect(MockMvcResultMatchers.status().isOk()).andExpect(MockMvcResultMatchers.content().string("user home"));}@Testpublic void testShow() throws Exception {mvc.perform(MockMvcRequestBuilders.get("/user/show").param("id", "400")).andExpect(MockMvcResultMatchers.status().isOk());mvc.perform(MockMvcRequestBuilders.get("/user/show").param("id", "400")).andExpect(MockMvcResultMatchers.status().isOk()).andExpect(MockMvcResultMatchers.content().string("show400"));}
}

一个注解可以使测试类可以自动配置MockMvc这个类。

springboot test相关推荐

  1. 继承WebMvcConfigurer 和 WebMvcConfigurerAdapter类依然CORS报错? springboot 两种方式稳定解决跨域问题

    继承WebMvcConfigurer 和 WebMvcConfigurerAdapter类依然CORS报错???springboot 两种方式稳定解决跨域问题! 之前我写了一篇文章,来解决CORS报错 ...

  2. Dockerfile springboot项目拿走即用,将yml配置文件从外部挂入容器

    Dockerfile 将springboot项目jar包打成镜像,并将yml配置文件外挂. # 以一个镜像为基础,在其上进行定制.就像我们之前运行了一个 nginx 镜像的容器,再进行修改一样,基础镜 ...

  3. SpringBoot部署脚本,拿走即用!

    一个可以直接拿来使用的shell脚本,适用于springboot项目 #!/bin/bash # 这里可替换为你自己的执行程序,其他代码无需更改,绝对路径相对路径均可. # 若使用jenkins等工具 ...

  4. SpringBoot项目使用nacos,kotlin使用nacos,java项目使用nacos,gradle项目使用nacos,maven项目使用nacos

    SpringBoot项目使用nacos kotlin demo见Gitte 一.引入依赖 提示:这里推荐使用2.2.3版本,springboot与nacos的依赖需要版本相同,否则会报错. maven ...

  5. springboot整合swagger2之最佳实践

    来源:https://blog.lqdev.cn/2018/07/21/springboot/chapter-ten/ Swagger是一款RESTful接口的文档在线自动生成.功能测试功能框架. 一 ...

  6. SpringBoot中实现quartz定时任务

    Quartz整合到SpringBoot(持久化到数据库) 背景 最近完成了一个小的后台管理系统的权限部分,想着要扩充点东西,并且刚好就完成了一个自动疫情填报系统,但是使用的定时任务是静态的,非常不利于 ...

  7. Springboot 利用AOP编程实现切面日志

    前言 踏入Springboot这个坑,你就别想再跳出来.这个自动配置确实是非常地舒服,帮助我们减少了很多的工作.使得编写业务代码的时间占比相对更大.那么这里就讲一下面向切面的日志收集.笔者使用lomb ...

  8. 【Springboot】日志

    springBoot日志 1.目前市面上的日志框架: 日志门面 (日志的抽象层):                JCL(Jakarta Commons Logging)                ...

  9. 【springboot】配置

    配置文件 SpringBoot使用一个全局的配置文件,配置文件名是固定的: •application.properties •application.yml 配置文件的作用:修改SpringBoot自 ...

  10. 【springboot】入门

    简介: springBoot是spring团队为了整合spring全家桶中的系列框架做研究出来的一个轻量级框架.随着spring4.0推出而推出,springBoot可以説是J2SEE的一站式解决方案 ...

最新文章

  1. 雪鹰领主服务器维护,《雪鹰领主》7月14日维护更新公告
  2. Colors on the web
  3. SAP OData请求是如何通过OData Plugin路由到OData Offline Data Store的
  4. java——IO流整理(一)
  5. 文献阅读课10-Neural Relation Extraction for Knowledge Base Enrichment(提取+嵌入+消歧+规范化联合模型,实体已知,仅关系抽取,多词实体)
  6. 抽象工厂模式_设计模式——抽象工厂模式
  7. 【youcans 的 OpenCV 例程200篇】117. 形态学操作之顶帽运算
  8. MAC OS下使用JAVE将amr转mp3的坑
  9. CASS11:超越自我,再续辉煌!CASS10.1.6:延续经典,只为更好!
  10. 模型预测控制参数调整问题
  11. IT服务管理流程控制的绩效指标 KPI
  12. mysql建立唯一索引升序_MySQL数据库SQL优化技巧六之唯一索引
  13. L2-036 网红点打卡攻略
  14. Tryhackme-Web Hacking Fundamentals
  15. java的Serialization机制
  16. 如何做好虾皮跨境电商?关于Shopee店铺快速开单的真相!
  17. 宽带和网线有什么区别?
  18. 浏览器代理服务器出现问题
  19. [STM32]jlink RTT使用详解
  20. 一个实例说明PID 参数整定

热门文章

  1. 微机原理与接口技术-第二版-课后习题答案 绪论
  2. 申请办理美国亚马逊质量检验报告前,需准备什么资料?
  3. 对于如何彻底的卸载和删除Windows service,有如下方法
  4. java模拟借书系统E R图_作业—模拟借书系统
  5. 物料编码是计算机识别和检索物料的( ),物料编码是计算机识别和检索物料的。...
  6. 大学BBS年度十大原创淡黄笑话
  7. Mac双网卡路由设置实现内外网同时访问
  8. 使用TinyPNG的API进行图片压缩
  9. 需求:vue+svg实现连线功能
  10. Django-ftpserver 的两个坑