SpringBootTest 和Testng组成测试套件

SpringBootTest

可以在运行基于Spring Boot的测试的测试类上指定的注释。当没有定义特定的@ContextConfiguration(loader=…)时,使用SpringBootContextLoader作为缺省ContextLoader。

  • 当未使用嵌套的@Configuration且未指定显式类时,自动搜索@SpringBootConfiguration。
  • 允许使用properties属性定义自定义环境属性。
  • 允许使用args属性定义应用程序参数。
  • 提供对不同web环境模式的支持,包括启动一个完全运行的web服务器,在一个定义的或随机的端口上监听。
  • 注册teststtemplate和/或WebTestClient bean,以便在使用完全运行的web服务器的web测试中使用。

SpringBootTest配置项:

  • value() 将属性配置加载到springContext中,定义的bean中使用@Value("${key1}")或者@Value("#{key1}")则可加载,配置格式value = {"key1=value1","key2=value2"}
  • properties() 同上
  • args() 应用参数格式 args = {"--arg1=v1","--arg2=v2"}) ,可通过@Value("${arg1}")获取和ApplicationArguments中获取,当properties和args配置了相同的key时,args优先级更高
  • classes 指定类加载到ApplicationContext,便于快速测试。默认SpringBootTest会加载整个项目的Spring管理的bean
  • webEnvironment 测试web运行环境,默认使用MOCK方式
    • MOCK: 创建mockservlet环境如果
    • RANDOM_PORT:随机port端口
    • DEFINED_PORT:默认port端口
    • NONE:

AbstractTestNGSpringContextTests

@RunWith(SpringRunner.class)将junit将测试类运行到SpringRunner中,但默认使用的junit,如果测试框架使用testng则该注解无法正常使用(Spring管理的对象无法被加载),需要测试类继承AbstractTestNGSpringContextTests,该类继承了Spring TestContext框架在TestNg环境。继承该类的子类的测试方法执行时会委托给run(IHookCallBack callBack, ITestResult testResult)执行

package com.tank.srpingboot;

import net.bytebuddy.asm.Advice;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.springframework.web.client.RestTemplate;
import org.testng.Assert;
import org.testng.annotations.Test;

import static org.testng.Assert.*;

/**
 * @author tangkun
 * @date 2021-04-04
 */
//@RunWith(SpringRunner.class)
@SpringBootTest(
webEnvironment= SpringBootTest.WebEnvironment.DEFINED_PORT,
value = {"pay.maxAmount=200","key3=200"},
args = {"--arg1=v1","--arg2=v2","--key3=300"}

)
public class OrderControllerTest extends AbstractTestNGSpringContextTests {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    SysConfig sysConfig;

    @Value("${arg1}")
    private String arg1;

    @Value("${key3}")
    private int key3;

    @Autowired
    private ApplicationArguments args;

    @Test public void testPayAmount() {
        String userId = "0x1234";
        String amount = "10";
        String url = "http://localhost:8080/payAmount?userId=%s&amount=%s";
        url = String.format(url,userId,amount);
        ResponseEntity<String> result = restTemplate.getForEntity(url,String.class);
        System.out.println(result);

        Assert.assertEquals(sysConfig.getMaxAmount(),200);
    }

    @Test
    public void getArgs(){
        Assert.assertEquals("v1",arg1);
        Assert.assertEquals("v1",args.getOptionValues("arg1").get(0));
    }

    @Test
    public void getArgsAndProperties(){
        Assert.assertEquals(300,key3);
    }
}

IHookCallBack

AbstractTestNGSpringContextTests中run方法执行时,会调用IHookable的runTestMethod,该接口只能被TestNg实现。

  public void run(IHookCallBack callBack, ITestResult testResult) {
        Method testMethod = testResult.getMethod().getConstructorOrMethod().getMethod();
        boolean beforeCallbacksExecuted = false;

        try {
            this.testContextManager.beforeTestExecution(this, testMethod);
            beforeCallbacksExecuted = true;
        }
        catch (Throwable ex) {
            this.testException = ex;
        }

        if (beforeCallbacksExecuted) {
                      //真正的测试方法会委托给callBack的runTestMethod执行
            callBack.runTestMethod(testResult);
            this.testException = getTestResultException(testResult);
        }

        try {
            this.testContextManager.afterTestExecution(this, testMethod, this.testException);
        }
        catch (Throwable ex) {
            if (this.testException == null) {
                this.testException = ex;
            }
        }

        if (this.testException != null) {
            throwAsUncheckedException(this.testException);
        }
    }
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容