SpringBoot使用随机端口测试

1,350 阅读2分钟

工作中经常会需要同时启动多个服务进行测试,特别是在高可用(配置中心、测试中心等基础设施)、负载均衡中常见。但是,我们一个应用只能有一个端口号,这就使得在本机测试的时候,不得不为同一个服务设置不同的端口来进行启动,采用随机端口的方式来设置各个服务实例,这样我们不用去编辑任何配置就可以在本地轻松地启动多个实例了。

同样以测试上面的两个 controller 方法为例。
点击获取更多完整的spring全家桶springcloud微服务课程。

1、编写测试根路径的单元测试用例

/**
* 使用随机端口方式SpringBoot的Controller 层做单元测试,需要启动项目才能进行 
*
*/ @RunWith(SpringRunner.class) @SpringBootTest(classes= {Springboot01Application.class}, 
webEnvironment=WebEnvironment.RANDOM_PORT) // 添加启动类和指定测试环境是随机端口 
public class Springboot01ApplicationTests2 { @Autowired private TestRestTemplate restTemplate; 
@Test

public void testIndex() { 
// 直接返回对象 String result = restTemplate.getForObject("/", String.class); 
// 测试根路径 Assert.assertEquals("Hello World!", result); 
// 断言是否返回 Hello World! 
} 
}

其中:
使用 @RunWith(SpringRunner.class) 作为测试入口, @SpringBootTest(classes= {Springboot01Application.class}, webEnvironment=WebEnvironment.RANDOM_PORT) 注解中指定启动类,同时必须指定测试环境设置成随机端口,这个测试环境可以在 WebEnvironment 枚举中查找,默认是MOCK使用 TestRestTemplate 作为请求的 http client,跟 MockMvc 对象功能类似。

不过TestRestTemplate主要用于接口测试。包含有 getForObject(String url, Class responseType, Map<String, ?> urlVariables),执行一个 GET 请求,参数:url 为请求地址,responseType为接收的结果数据类型,urlVariables为请求参数,不是必选。它返回的是一个对象。同理可以的还有 postForObject()、putForObject()、deleteForObject()等针对不同请求方式的访问方法。

2、对 json 数据进行测试

@Test 
public void testFindObj() { Course course = restTemplate.getForObject("/find", Course.class); 
// 校验获取返回的结果对象的 name 是否是 Spring Boot Assert.assertEquals("Spring Boot", course.getName()); }@Test public void testFindEntity() { // ResponseEntity是响应实体,里面封装了请求的响应信息,包括状态码,响应头、响应实体等,调用 getForEntity()方法返回 ResponseEntity<Course> responseEntity = restTemplate.getForEntity("/find", Course.class); // 校验响应的状态码是否200即请求成功 Assert.assertEquals(200, responseEntity.getStatusCodeValue()); 
// 校验获取返回的结果对象的 name 是否是 Spring Boot Assert.assertEquals("Spring Boot", responseEntity.getBody().getName()); }

其中注意的是调用了getForEntity(String url, Class responseType, Map<String, ?> urlVariables),执行一个 GET请求方式,返回的是一个 ResponseEntity 对象,里面封装了请求的响应信息,包括状态吗,响应头、响应实体等数据。

通过调用这个对象的getStatusCodeValue()获取响应码,getBody()获取响应体。传入的参数跟getForObject()方法一样。同理还有postForEntity()、putForEntity()、deleteForEntity()等针对不同请求方式的访问方法。