概述
官方文档:http://wiremock.org/docs/
其它资料:https://www.cnblogs.com/tanglang/p/4791198.html
WireMock是一个开源的测试工具,支持HTTP响应存根、请求验证、代理/拦截、记录和回放。最直接的用法:
- 为Web/移动应用构建Mock Service
- 快速创建Web API原型
- 模拟Web Service中错误返回
- 录制HTTP请求和回放
一般开发项目都会把前端组和Service组分开,或者服务间存在依赖的关系,当进度不一致时,可以根据接口构建Mock Service,模拟不同输入/数据/场景,这样不至于影响两组的开发进度。构建Mock Service方法很多,如:开源工具moco、postman、node.js、soapUI。其中soapUI还可以对Service进行功能/性能测试,功能非常齐全,与soapUI相比,Wiremock好在轻便,一个jar包基本能够满足大多数需求,当然,也可以把它引用写进测试代码里。
通过可执行jar文件单独运行:
1、下载可执行jar文件:http://repo1.maven.org/maven2/com/github/tomakehurst/wiremock-standalone/2.13.0/wiremock-standalone-2.13.0.jar
2、通过以下命令运行:
java -jar wiremock-standalone-2.13.0.jar
默认绑定端口是8080
如果我们已经有请求/响应json文件(可以是手动编写也可以是录制生成、修改),可以先把这些文件放在jar文件同一级目录的mappings文件夹中(默认的路径),然后再执行jar文件,当然也可以在执行jar文件时指定到json文件所在的位置
通过命令行参数做更多配置:
--port:设置http端口号,如:--port 9999
--https-port:如果声明该参数,则表示开启HTTPS端口
--root-dir:设置文件根目录,也就是mappings文件夹和__files文件夹所在的位置,其中mappings是请求/响应json文件所在的目录,也是录制生成文件的目录,默认为jar文件所在的当前目录
--record-mappings:设置录制生成文件的目录,默认为jar文件当前目录的mappings文件夹
更多配置请看:http://wiremock.org/docs/running-standalone/
3、启动后,我们便可以访问该HTTP服务器了
例如,端口号为8080,我们手动编写的json文件如下:
{
"request" : {
"url" : "/userInfo?name=liming&age=23",
"method" : "GET"
},
"response" : {
"status" : 200,
"jsonBody" : {
"name":"方法方法是是",
"age" : "13"
},
"headers": {
"Content-Type": "application/json ; charset=UTF8"
}
}
}
1)可以通过http://localhost:8080/userInfo?name=liming&age=23来调用模拟的userInfo接口
2)通过http://localhost:8080/__admin/可以看到当前wiremock模拟的所有端口信息
3)jar包自带了json文件的使用手册,访问http://localhost:8080/__admin/docs/可看到如下界面:
点击Swagger_UI可以看到具体每种请求JSON的写法:
我们也可以在官网上查看JSON文件的写法:http://wiremock.org/docs/api/
4、录制/回放
1)打开:http://localhost:8080/__admin/recorder/可看到如下界面:
2)输入目标URL,点击Record按钮进入录制状态。
3)以上面的userInfo接口为例,我们通过浏览器访问http://localhost:8080/userInfo?name=liming&age=23,wiremock收到请求后,然后向目标服务器发起请求http://localhost:9001/userInfo?name=liming&age=23,然后把目标服务器返回的结果返回给我们,同时记下请求和响应的内容。
4)点击stop按钮停止录制,此时可以看到在mappings文件夹中生成一个json文件,记录了之前的请求和响应内容。
5)后续再访问http://localhost:8080/userInfo?name=liming&age=23时,wiremock便会从之前录制的json文件中获取响应信息返回给我们,我们也可以修改json文件从而改变请求响应的内容。
通过引入依赖的方式使用
wiremock源码:https://github.com/spring-cloud/spring-cloud-contract/tree/master
官方例子:https://github.com/spring-cloud/spring-cloud-contract/tree/master/samples/wiremock-tomcat
具体代码请看(码云):https://gitee.com/wudiyong/WireMockEurekaServer.git
1、引入wiremock依赖
<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock</artifactId>
<version>2.12.0</version>
</dependency>
或
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-contract-wiremock</artifactId>
</dependency>
2、创建实例并启动
1)如果只是模拟一个普通的HTTP服务端,可以直接在main函数中创建WireMockServer实例并启动:
FileSource filesRoot = new SingleRootFileSource(wireMockFilesRoot+"/"+appName);
WireMockServer wireMockServer = new WireMockServer(WireMockConfiguration.options()
.bindAddress(wireMockAddress).port(Integer.parseInt(wireMockPort)).fileSource(filesRoot));
wireMockServer.start();
2)如果在Spring Boot环境中使用,可以通过以下方式:
@Bean
public WireMockServer wireMockServer(){
//创建wiremock对象
FileSource filesRoot = new SingleRootFileSource(wireMockFilesRoot+"/"+appName);
WireMockServer wireMockServer = new WireMockServer(WireMockConfiguration.options()
.bindAddress(wireMockAddress).port(Integer.parseInt(wireMockPort)).fileSource(filesRoot));
wireMockServer.start();
return wireMockServer;
}
wireMockFilesRoot+"/"+appName:mappings文件夹所在的位置
3)如果与JUnit结合使用,可以通过如下方式:
@Rule
public WireMockRule wireMockRule = new WireMockRule(options().port(8080));
前两种方式和执行jar文件启动方式一样,都可以通过http://localhost:8080/__admin/recorder/来开启/关闭录制
3、特别地,我们需要模拟一个Eureka服务端,我们的服务需要向注册中心注册,所以,选择上面第二种方式使用wiremock
程序中包含两个web服务:
一个是Spring Boot web,用于向注册中心注册,接收请求,然后将请求发到wiremock服务器
另一个是wiremock,用于模拟返回结果
代码如下:
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.tomakehurst.wiremock.WireMockServer;
@RestController
public class MockController {
@Autowired
RestTemplate restTemplate;
@Autowired
WireMockServer wireMockServer;
@Value("${wireMock.address}")
private String wireMockAddress;
@Value("${wireMock.port}")
private String wireMockPort;
private static boolean isProxy = false;
@RequestMapping(value = "/**", method = RequestMethod.GET)
public Object getAll(HttpServletRequest httpServletRequest ,@RequestParam Map<String, Object> requestMap) {
StringBuffer mocoUrl = new StringBuffer();
mocoUrl.append("http://").append(wireMockAddress).append(":")
.append(wireMockPort).append(httpServletRequest.getServletPath());
if(!requestMap.isEmpty()){
mocoUrl.append("?");
boolean first = true;
for(String key:requestMap.keySet()){
if(!first){
mocoUrl.append("&");
}
first = false;
mocoUrl.append(key).append("={").append(key).append("}");
}
}
String jsonStr = restTemplate.getForEntity(mocoUrl.toString(), String.class,requestMap).getBody();
Object object = JSONObject.parse(jsonStr);
return object;
}
@RequestMapping(value = "/**", method = RequestMethod.POST)
public Object postAll(HttpServletRequest httpServletRequest ,@RequestBody Object requestBody) {
String requestJsonStr = JSON.toJSONString(requestBody);
StringBuffer mocoUrl = new StringBuffer();
mocoUrl.append("http://").append(wireMockAddress).append(":")
.append(wireMockPort).append(httpServletRequest.getServletPath());
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
headers.setContentType(type);
//
headers.add("Accept", MediaType.APPLICATION_JSON.toString());
HttpEntity<String> formEntity = new HttpEntity<String>(requestJsonStr, headers);
String jsonStr = restTemplate.postForEntity(mocoUrl.toString(), formEntity,String.class).getBody();
Object object = JSONObject.parse(jsonStr);
return object;
}
@RequestMapping(value = "/proxyOn" , method = RequestMethod.GET)
public String proxyOn(@RequestParam String proxyPath){
if(isProxy){
wireMockServer.stopRecording();
}
isProxy = true;
//开启录制
wireMockServer.startRecording(proxyPath);
return "Proxy is on! The proxyPath is:" + proxyPath;
}
@RequestMapping(value = "/proxyOff",method = RequestMethod.GET)
public String proxyOff(){
if(isProxy){
//关闭录制
wireMockServer.stopRecording();
}
isProxy = false;
return "Proxy is off!";
}
}
录制的步骤如下:
1)启动自己编写的模拟服务器和目标服务器
2)设置被录制的目标服务器地址,然后开启录制,有两种方式:通过wiremock提供的图形界面设置、调用上面代码提供的接口
3)触发客户端发送请求,如果模拟服务器和目标服务器同名,则该请求会按照一定策略分配到不同的服务器,默认是轮询方式,也就是说,触发两次,会有一次请求到达模拟服务器
4)关闭录制,此时看到mappings文件夹下生成了一个新的json文件,至此录制完成,当然可以一起录制多个请求,每次请求对应一个json文件
录制结束后,后续的测试便不需要启动目标服务器了,模拟服务器会根据请求的url和参数返回对应的结果,可以根据需要修改录制结果或手动编写json文件。
最后
以上就是炙热蜜蜂为你收集整理的Web服务模拟器——wiremock的全部内容,希望文章能够帮你解决Web服务模拟器——wiremock所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复