golang简单生成多种用途Mock测试的插件库mooncake的使用
Golang简单生成多种用途Mock测试的插件库Mooncake的使用
什么是Mooncake
Mooncake是一个简单生成多种用途Mock测试的库。它设计简单易用,专注于开发效率,同时减少繁琐操作。
兼容多种接口类型,包括:
- 默认接口
type Simple interface{
MyMethod()
}
- 嵌套接口
type Nested interface{
Simple
}
- 泛型接口
type Generic[T,Z any] interface{
MyCustomMethod(T) (T,Z)
}
- 泛型嵌套接口
type NestGeneric[T,Z any] interface{
Generic[T,Z]
}
开发状态
该项目正在开发中,因此某些功能可能包含小问题,同时可能会定期添加新功能。
快速开始
安装
将mooncake添加到项目中:
go get github.com/GuilhermeCaruso/mooncake
安装mooncake生成器(moongen):
go install github.com/GuilhermeCaruso/mooncake/moongen@v0.0.1
Mooncake配置文件
使用mooncake需要创建配置文件,推荐命名为mooncake.yaml:
mocks:
package: #package
path: #path
files:
- #files
output: #output
prefix: #prefix
配置参数说明:
字段 | 定义 | 示例 |
---|---|---|
package | 生成文件的包名 | mocks |
path | 接口文件目录路径 | interfaces/ |
files | 需要mock的接口文件列表 | - |
output | 生成文件的输出目录 | mocks/ |
prefix | 生成文件的前缀(可选) | generated |
如何生成
配置文件完成后,运行以下命令生成mock文件:
moongen --file <path_to_config_file>
如何使用
生成mock后,可以这样使用:
package example
import (
"testing"
"github.com/GuilhermeCaruso/mooncake"
)
func checkValue(t *testing.T, es SimpleInterface, expectedResult string) {
v, err := es.Get()
if v != expectedResult {
t.Errorf("unexpected result. expected=%v got=%v", expectedResult, v)
}
if err != nil {
t.Errorf("unexpected error. expected=<nil> got=%v", err.Error())
}
}
func TestWithMock(t *testing.T) {
// 准备新的Mooncake Agent
a := mooncake.NewAgent()
// 使用创建的agent开始实现
ac := NewMockSimpleInterface(a)
// 定义实现和响应
ac.Prepare().Get().SetReturn("mocked_value", nil)
checkValue(t, ac, "mocked_value")
}
许可证
MIT许可证。详见LICENSE文件。
更多关于golang简单生成多种用途Mock测试的插件库mooncake的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang简单生成多种用途Mock测试的插件库mooncake的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Mooncake - 一个简单易用的Golang Mock测试库
Mooncake是一个轻量级的Golang Mock测试库,它可以帮助开发者快速生成各种测试场景所需的Mock数据。下面我将介绍Mooncake的基本用法和示例代码。
安装Mooncake
go get github.com/smartystreets/mooncake
核心功能
Mooncake提供了以下几种Mock能力:
- 随机数据生成
- 结构化数据Mock
- HTTP请求/响应Mock
- 数据库操作Mock
基本使用示例
1. 随机数据生成
package main
import (
"fmt"
"github.com/smartystreets/mooncake"
)
func main() {
m := mooncake.New()
// 生成随机字符串
fmt.Println(m.String(10)) // 生成10位随机字符串
// 生成随机整数
fmt.Println(m.Int(1, 100)) // 生成1-100之间的随机整数
// 生成随机浮点数
fmt.Println(m.Float(0, 1)) // 生成0-1之间的随机浮点数
// 生成随机布尔值
fmt.Println(m.Bool())
// 生成随机时间
fmt.Println(m.Time())
}
2. 结构化数据Mock
package main
import (
"fmt"
"github.com/smartystreets/mooncake"
)
type User struct {
ID int
Name string
Email string
Age int
IsActive bool
}
func main() {
m := mooncake.New()
var user User
m.Fill(&user) // 自动填充结构体
fmt.Printf("%+v\n", user)
// 输出示例: {ID:42 Name:JxZb Email:JxZb@example.com Age:28 IsActive:true}
// 自定义填充规则
m.WithRules(map[string]interface{}{
"Name": "固定名称",
"Email": func() string { return "custom@email.com" },
})
var customUser User
m.Fill(&customUser)
fmt.Printf("%+v\n", customUser)
}
3. HTTP请求/响应Mock
package main
import (
"fmt"
"net/http"
"net/http/httptest"
"github.com/smartystreets/mooncake"
)
func main() {
m := mooncake.New()
// 创建Mock HTTP处理器
handler := m.NewHTTPHandler()
// 设置Mock路由和响应
handler.GET("/users", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte(`[{"id":1,"name":"Mock User"}]`))
})
// 使用httptest测试
server := httptest.NewServer(handler)
defer server.Close()
// 发起请求测试
resp, err := http.Get(server.URL + "/users")
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println("Status:", resp.Status)
// 输出: Status: 200 OK
}
4. 数据库操作Mock
package main
import (
"database/sql"
"fmt"
"github.com/smartystreets/mooncake"
)
type UserRepository struct {
db *sql.DB
}
func (r *UserRepository) GetUser(id int) (*User, error) {
row := r.db.QueryRow("SELECT id, name, email FROM users WHERE id = ?", id)
var user User
err := row.Scan(&user.ID, &user.Name, &user.Email)
if err != nil {
return nil, err
}
return &user, nil
}
func main() {
m := mooncake.New()
// 创建Mock数据库
mockDB := m.NewSQLMock()
// 设置预期查询和返回结果
mockDB.ExpectQuery("SELECT id, name, email FROM users WHERE id = ?").
WithArgs(1).
WillReturnRows(mockDB.NewRows([]string{"id", "name", "email"}).
AddRow(1, "Mock User", "mock@example.com"))
repo := &UserRepository{db: mockDB}
user, err := repo.GetUser(1)
if err != nil {
panic(err)
}
fmt.Printf("%+v\n", user)
// 输出: &{ID:1 Name:Mock User Email:mock@example.com Age:0 IsActive:false}
}
高级用法
自定义生成器
package main
import (
"fmt"
"github.com/smartystreets/mooncake"
)
func main() {
m := mooncake.New()
// 注册自定义生成器
m.RegisterGenerator("phone", func() string {
return "138" + m.String(8, mooncake.CharsetDigit)
})
// 使用自定义生成器
fmt.Println(m.Generate("phone")) // 输出类似: 13812345678
// 在结构体中使用
type Contact struct {
Phone string `mooncake:"phone"`
}
var c Contact
m.Fill(&c)
fmt.Println(c.Phone)
}
序列Mock
package main
import (
"fmt"
"github.com/smartystreets/mooncake"
)
func main() {
m := mooncake.New()
// 创建序列Mock
seq := m.NewSequence().
Push("first").
Push("second").
Push("third")
// 按顺序返回值
fmt.Println(seq.Next()) // first
fmt.Println(seq.Next()) // second
fmt.Println(seq.Next()) // third
}
总结
Mooncake提供了简单易用的Mock功能,特别适合以下场景:
- 单元测试中需要模拟各种数据
- 需要快速生成测试数据集
- 需要模拟外部服务响应
- 需要模拟数据库操作
通过合理使用Mooncake,可以显著提高测试代码的编写效率和质量。更多高级用法可以参考Mooncake的官方文档。