Java SpringBoot Junit5

@Test

在Springboot2.0版本之后,Junit就是5.几的版本,在方法上添加@Test即可

  1. @Test
  2. void fun1(){
  3. int res = 1+1;
  4. Assertions.assertEquals(2,res);
  5. System.out.println(123);
  6. }

@BeforeEach & @AfterEach

每执行一个@Test就会执行一次

  1. @BeforeEach
  2. void before(){
  3. System.out.println("before");
  4. }
  5. @AfterEach
  6. void after(){
  7. System.out.println("after");
  8. }
  9. @Test
  10. void fun1(){
  11. int res = 1+1;
  12. Assertions.assertEquals(2,res);
  13. System.out.println(123);
  14. }
  15. @Test
  16. void fun2(){
  17. System.out.println(456);
  18. }

SpringBoot整合Junit5 常用注解 - 图1

@BeforeAll & @AfterAll

无论有多少个@Test都只执行一次,且@BeforeAll & AfterAll下的方法必须是静态方法

  1. @BeforeAll
  2. static void init(){
  3. System.out.println("init");
  4. }
  5. @AfterAll
  6. static void destory(){
  7. System.out.println("destory");
  8. }
  9. @BeforeEach
  10. void before(){
  11. System.out.println("before");
  12. }
  13. @AfterEach
  14. void after(){
  15. System.out.println("after");
  16. }
  17. @Test
  18. void fun1(){
  19. int res = 1+1;
  20. Assertions.assertEquals(2,res);
  21. System.out.println(123);
  22. }
  23. @Test
  24. void fun2(){
  25. System.out.println(456);
  26. }

SpringBoot整合Junit5 常用注解 - 图2

@SpringBootTest

在SpringBoot项目中,在测试类中new 一个类时,这个类可能同时会涉及到其他的Bean,而原来的@Test并不会涉及到SpringBoot的上下文,所以在SpringBoot项目中编写测试类时,会在类上添加@SpringBootTest,在创建项目选择 Spring Initializr创建SpringBoot项目时,目录下会有一个Test文件,就会看到自动创建好的Test类上带有@SpringBootTest
同时也能配合@Autowired的注入

  1. @SpringBootTest //能够初始化springboot的上下文,防止new Serv01 的对象同时依赖其他的Bean
  2. public class Test2 {
  3. @Autowired
  4. Serv01 serv01;
  5. @Test
  6. void t1(){
  7. int add = serv01.add(1, 1);
  8. Assertions.assertEquals(2,add);
  9. System.out.println(11);
  10. }
  11. }

当然,运行这个带@SpringBootTest的测试用例,也会启动SpringBoot项目

@MockBean

通过mock来做到一个模拟,假如测试需要写入数据库,可能会造成一些不可挽回的操作,对这些危险的操作会使用mock来进行一个模拟
看下面的代码

  1. @SpringBootTest //能够初始化springboot的上下文,防止new Serv01 的对象同时依赖其他的Bean
  2. public class Test2 {
  3. @MockBean
  4. Serv01 serv01;
  5. @Test
  6. void t1(){
  7. int add = serv01.add(1, 1);
  8. Assertions.assertEquals(2,add);
  9. System.out.println(11);
  10. }
  11. }

通过断点得知 变量add 等于0
原因就是在SpringBoot上下文的serv01的这个bean已经被mock替换掉了,因为mock并没有任何指定操作,所以int变量add 只会有默认值 0
对mock添加一些指定操作

  1. @SpringBootTest
  2. public class Test2 {
  3. @MockBean
  4. Serv01 serv01;
  5. @Test
  6. void t1(){
  7. when(serv01.add(1,1)).thenReturn(3);
  8. int add = serv01.add(1, 1);
  9. Assertions.assertEquals(2,add);
  10. System.out.println(11);
  11. }
  12. }

SpringBoot整合Junit5 常用注解 - 图3
再次修改代码,在Serv01添加sub的方法,然后运行测试,可以发现在指定规则的add方法,得出的结果是3,而未指定规则的sub方式则默认int变量为0
如果想让sub按照原来的方式进行测试,不想被@MockBean影响,可以使用@SpyBean

@SpyBean

@SpyBean是介于@MockBean@Autowired之间,在配置了规则的方法就按配置规则的执行,没有配置的就按原来的方法执行测试。如果再创建一个serv02,让serv01调用serv02的方法,运行的结果还是一样吗?

  1. @Service
  2. public class Serv02 {
  3. int add2(int a, int b){
  4. return a+b;
  5. }
  6. }
  1. @Service
  2. public class Serv01 {
  3. @Autowired
  4. Serv02 serv02;
  5. public int add(int a,int b){
  6. return serv02.add2(a,b);
  7. }
  8. public int sub(int a,int b){
  9. return a-b;
  10. }
  11. }
  1. @SpringBootTest //能够初始化springboot的上下文,防止new Serv01 的对象同时依赖其他的Bean
  2. public class Test2 {
  3. @SpyBean
  4. Serv01 serv01;
  5. @MockBean
  6. Serv02 serv02;
  7. @Test
  8. void t1(){
  9. when(serv01.add(1,1)).thenReturn(3);
  10. int add = serv01.add(1, 1);
  11. int sub = serv01.sub(2,1);
  12. Assertions.assertEquals(3,add);
  13. Assertions.assertEquals(1,sub);
  14. System.out.println(11);
  15. }
  16. }

可以看到运行成功,即使mock的是serv02,通过serv01调用的add方法调用serv02的add2方法,照样运行成功!