golang模拟HTTP服务器和消费者驱动契约测试插件库mockingjay的使用
Golang模拟HTTP服务器和消费者驱动契约测试插件库mockingjay的使用
Mockingjay简介
Mockingjay是一个Golang库,它允许你定义消费者和生产者之间的契约,通过配置文件你可以获得:
- 一个快速启动的模拟服务器用于集成测试
- 可配置以模拟调用其他服务的不可预测行为
- 消费者驱动契约测试(CDCs)来验证你的真实下游服务
运行模拟服务器
示例配置
---
- name: My very important integration point
request:
uri: /hello
method: POST
body: "Chris" # * matches any body
response:
code: 200
body: '{"message": "hello, Chris"}' # * matches any body
headers:
content-type: application/json
# define as many as you need...
启动服务器
$ mockingjay-server -config=example.yaml -port=1234 &
2015/04/13 14:27:54 Serving 3 endpoints defined from example.yaml on port 1234
$ curl http://localhost:1234/hello
{"message": "hello, world"}
检查配置是否与真实服务器兼容
$ mockingjay-server -config=example.yaml -realURL=http://some-real-api.com
2015/04/13 21:06:06 Test endpoint (GET /hello) is incompatible with http://some-real-api - Couldn't reach real server
2015/04/13 21:06:06 Test endpoint 2 (DELETE /world) is incompatible with http://some-real-api - Couldn't reach real server
2015/04/13 21:06:06 Failing endpoint (POST /card) is incompatible with http://some-real-api - Couldn't reach real server
2015/04/13 21:06:06 At least one endpoint was incompatible with the real URL supplied
查看Mockingjay接收的请求
http://{mockingjayhost}:{port}/requests
使模拟服务器不稳定
Mockingjay有一个"猴子"配置,可以让你的模拟服务行为不稳定。这在性能测试中很有用,可以模拟更真实的场景。
猴子配置示例
---
# Writes a different body 50% of the time
- body: "This is wrong :( "
frequency: 0.5
# Delays initial writing of response by a second 20% of the time
- delay: 1000
frequency: 0.2
# Returns a 404 30% of the time
- status: 404
frequency: 0.3
# Write 10,000,000 garbage bytes 9% of the time
- garbage: 10000000
frequency: 0.09
启动不稳定的服务器
$ mockingjay-server -config=examples/example.yaml -monkeyConfig=examples/monkey-business.yaml
2015/04/17 14:19:53 Serving 3 endpoints defined from examples/example.yaml on port 9090
2015/04/17 14:19:53 Monkey config loaded
2015/04/17 14:19:53 50% of the time | Body: This is wrong :(
2015/04/17 14:19:53 20% of the time | Delay: 1s
2015/04/17 14:19:53 30% of the time | Status: 404
2015/04/17 14:19:53 9% of the time | Garbage bytes: 10000000
构建Mockingjay
要求
- Go 1.3+安装(设置$GOPATH等)
- golint
构建应用
$ go get github.com/quii/mockingjay-server
$ cd $GOPATH/src/github.com/quii/mockingjay-server
$ ./build.sh
MIT许可证
更多关于golang模拟HTTP服务器和消费者驱动契约测试插件库mockingjay的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang模拟HTTP服务器和消费者驱动契约测试插件库mockingjay的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang模拟HTTP服务器与消费者驱动契约测试:mockingjay
模拟HTTP服务器
在Golang中,我们可以使用标准库net/http/httptest
来轻松创建模拟HTTP服务器:
package main
import (
"fmt"
"net/http"
"net/http/httptest"
)
func main() {
// 创建模拟服务器
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case "/api/users":
if r.Method == "GET" {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
fmt.Fprintln(w, `[{"id":1,"name":"John"},{"id":2,"name":"Jane"}]`)
} else {
w.WriteHeader(http.StatusMethodNotAllowed)
}
case "/api/orders":
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
fmt.Fprintln(w, `{"orderId":"12345","status":"processing"}`)
default:
w.WriteHeader(http.StatusNotFound)
fmt.Fprintln(w, `{"error":"not found"}`)
}
}))
defer server.Close()
fmt.Println("Mock server running at:", server.URL)
// 这里可以添加客户端代码来测试这个模拟服务器
// 例如使用http.Get(server.URL + "/api/users")
}
使用mockingjay进行消费者驱动契约测试
mockingjay是一个Go库,用于创建基于契约的模拟服务器。它允许你定义预期的请求和响应,并验证实际调用是否符合契约。
安装mockingjay
go get github.com/quii/mockingjay-server
基本使用示例
package main
import (
"fmt"
"github.com/quii/mockingjay-server/mockingjay"
"net/http"
)
func main() {
// 定义契约端点
endpoints := []mockingjay.FakeEndpoint{
{
Name: "Get user by ID",
CDCDisabled: false,
Request: mockingjay.Request{
Method: "GET",
Path: "/users/123",
Headers: map[string]string{
"Accept": "application/json",
},
},
Response: mockingjay.Response{
Code: http.StatusOK,
Body: `{"id":123,"name":"John Doe"}`,
Headers: map[string]string{
"Content-Type": "application/json",
},
},
},
{
Name: "Create user",
CDCDisabled: false,
Request: mockingjay.Request{
Method: "POST",
Path: "/users",
Headers: map[string]string{
"Content-Type": "application/json",
},
Body: `{"name":"New User"}`,
},
Response: mockingjay.Response{
Code: http.StatusCreated,
Body: `{"id":456,"name":"New User"}`,
Headers: map[string]string{
"Content-Type": "application/json",
},
},
},
}
// 创建模拟服务器
server := mockingjay.NewServer(endpoints)
fmt.Println("Mockingjay server running on", server.URL)
// 保持服务器运行
select {}
}
验证契约
mockingjay不仅可以模拟服务,还可以验证实际服务是否符合契约:
func TestRealServiceAgainstContract(t *testing.T) {
endpoints := []mockingjay.FakeEndpoint{
// 定义你的契约端点...
}
realServiceURL := "http://real-service:8080"
// 创建验证器
validator := mockingjay.NewValidator(endpoints, realServiceURL)
// 运行验证
results := validator.Validate()
if !results.Valid() {
t.Errorf("Real service failed contract tests: %v", results)
}
}
高级特性
-
匹配器:可以使用正则表达式或自定义匹配器来匹配请求
Request: mockingjay.Request{ Method: "GET", Path: "/users/[0-9]+", Headers: map[string]string{ "Accept": "application/json", }, },
-
延迟响应:模拟网络延迟
Response: mockingjay.Response{ Code: http.StatusOK, Body: `{"status":"ok"}`, Delay: 200 * time.Millisecond, // 200ms延迟 },
-
动态响应:基于请求生成响应
Response: mockingjay.Response{ Code: http.StatusOK, BodyFunc: func(r *http.Request) string { return fmt.Sprintf(`{"requestedPath":"%s"}`, r.URL.Path) }, },
实际应用建议
- 在CI/CD管道中:将契约测试作为持续集成的一部分
- 微服务开发:在服务消费者和提供者之间建立明确的契约
- 前端开发:在后端API完成前,使用模拟服务器进行前端开发
- 测试隔离:在单元测试中隔离外部依赖
通过使用这些技术,你可以创建更可靠、更可维护的API服务,并确保服务提供者和消费者之间的契约得到遵守。