一、写在前面
最近在写springcloud项目的单元测试,遇到了一些问题,写了一个测试基础类。
二、测试基础类
2.1测试基础类
由于我们使用的是springcloud架构,微服务很多,所有在进行单元测试时需要定义一个整体的测试基础类,其他微服务需要进行单元测试时仅需要继承这个基础类即可。不用每个微服务都写配置类
springcloud单元测试基础测试类2.2单元测试基础类讲解
2.2.1 启动加载上线文
@SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.DEFINED_PORT)
这个标签是定义使用默认的端口,这个端口有MOCK、RANDOM_PORT、DEFINED_PORT、NONE这几种选择,我这里使用的是DEFINED_PORT,这个端口是从配置文件里读取的。
同是,在@SpringBootTest可以指定启动类,如果不写就是默认的springcloud的main启动类
2.2.2自定义配置测试属性值
在测试加载上下文的过程中会去加载application.properties文件里的配置,但是我测试和正式环境配置的配置不一致,比如在正式环境下需要把注册eureka设置为true,但是测试的时候并不需要注册。有两种解决方案。
第一种是增加一份配置文件application-test.application,在这里单独写上测试需要的配置。然后在测试基础类上选择这个@ActiveProfiles("test")。这个的缺点是测试侵入了原有代码。
第二种方法是自定义覆盖application.properties文件里的配置。以key=value的方式重写配置,最终项目测试启动时会使用覆盖的设置,无代码侵入性。
@TestPropertySource(properties= {"eureka.client.register-with-eureka=false",
"eureka.client.fetch-registry=false",
"base.server.url=http://localhost:8888",
"server.port=8888"})
在单元测试的过程中,单独启动微服务会报错注册不到eureka,至使测试过程中错误日志很多,在这里设置eureka.client.register-with-eureka=false,eureka.client.fetch-registry=false即可。
2.2.3 TestRestTemplate封装
在基础测试类里对原生TestRestTemplate进行了封装,像很多接口传参的header都是json类型的,没必要每次都在测试代码里写,对TestRestTemplate进行封装后直接调用即可。
1、POST请求,请求参数为json类型
POST请求,请求参数为json在这个方法里封装了请求头header,并且判断了请求接口的状态,用户只需判断接口返回值的断言。
自定义断言接口2、POST请求,请求参数为bean类型
POST请求,请求参数为bean3、GET请求封装
Get请求4、DELETE请求封装
DELETE请求封装3基础测试类使用
对本基础测试类的使用仅需要继承
基础测试类使用需要传入的四个参数讲解:
第一个serverUrl,这个在baseUrl里已经定义了http://localhost:8888地址,这里需要传入的是@RestController接口的路径,基础测试类会自动拼接
第二个参数reqJson,这个是请求的参数
第三个参数返回值类型class,可以是Bean.class,根据具体接口而定
第四个接口是重写自定义断言,基础测试类里已经判断了接口是否为200,之后重写自定义断言,判断返回值的具体内容
4期间遇到的问题
在springcloud单元测试过程中遇到的比较棘手的问题有2个。
第一个是springcloud fegin的单元测试,如果再fegin服务端服务没部署的情况下,测试直接报错。这里使用的springcloud自带的contract契约测试解决的。
具体参考springcloud fegin契约测试解决方案(单元测试)
第二个遇到的问题是测试的代码里有异步的方法,单元测试主线程不等异步线程介绍就会提前结束测试,我们测试不到异步方法的逻辑,同时测试不到代码覆盖率
这里参考我的另一篇文章springcloud单元测试异步方法提前结束问题解决方案
网友评论