Go Generate 代替 Makefile使用方法详解

作者:小马别过河 时间:2024-04-27 15:28:18 

介绍

图灵完备性(Turing completeness)是通用计算机的一个属性,它表示一个程序可以写另一个程序。比如 go test 命令:它会扫描被测试的包,写一个包含测试内容的程序,然后编译运行。

可能你听得比较多的是元编程(meta-program)。这里不细究他们的区别。我们重点是,用程序生成另一个程序的场景,越来越广泛了。比如:

  • protobufs: 根据 pb 文件(.proto)生成 go 代码文件(.pb.go)

  • yacc: 根据 yacc 文件(.y)生成 go 代码文件

  • bindata: 二进制文件(如 JPEG)转成 go 的 bytes 数组

  • mockery: 根据 go 的 interface 生成 Mock 对象(依赖 stretchr/testify/mock 包)。

自动生成代码的命令,该如何集成进项目里面?一般来说,我们可以借助外部的工具,如 Make。使用 Go 1.4 新增的 go generate 命令,就可以避免外部工具了。

Mockery

我们以 mockery 为例,关于 mockery 生成的 Mock 对象,我之前的文章有介绍过:Go 库:单元测试利器 testify。

比如我们定义了 Greeter 接口,作为 Hello 的参数(代码本身无意义,仅做示例):

// greet.go 文件
package greet
type Greeter interface {
Greet() string
}
// 加上"hello"前缀
func Hello(g Greeter) string {
return "hello " + g.Greet()
}

我们要给 Hello 函数写单元测试的话,就需要为 Greeter 写一个 Mock 对象。我们可以使用 mockery 来生成。

安装 mockery:

go install github.com/vektra/mockery/v2@latest

为当前包下的所有 interface 生成 mock 对象,输出到 mocks 目录。

mockery --output mocks/ --dir . --all

我们查看目录文件:

➜ tree
.
├── greet.go
└── mocks             // mockery 生成的 mock 对象
   └── Greeter.go
1 directory, 2 files

关于 mockery 的说明,我们可以查看仓库:github.com/vektra/mock…。现在,我们可以为 Hello 写单元测试了:

// greet_test.go 文件
package greet
import (
"example/greet/mocks"
"testing"
"github.com/stretchr/testify/assert"
)
func TestHello(t *testing.T) {
 // 实例化 mock 对象
greeter := new(mocks.Greeter)
 // 设置预期,当请求 greeter.Greet() 时,返回 "world"
greeter.On("Greet").Return("world")
want := "hello world"
got := Hello(greeter)
 // 断言相等
assert.Equal(t, want, got)
}

Go Generate

我们接下来的问题是,Mockery 命令需要集成到项目里,我们可以写 shell 脚本、或者 Make 文件,但这些都不是 go tool 的工具。

用法

go generate 非常方便使用,只要当前目录的 .go 文件(如 greet.go 文件),加上备注:

//go:generate mockery --output mocks/ --dir . --all

我们先把刚刚生成的 mocks 目录删除,当前目录结构是:

➜   tree
.
├── greet.go
└── greet_test.go
0 directories, 2 files

然后进入 greet 包,执行 go generate:

➜  go generate  
01 Dec 22 20:06 CST INF Starting mockery dry-run=false version=v2.10.0
01 Dec 22 20:06 CST INF Walking dry-run=false version=v2.10.0
01 Dec 22 20:06 CST INF Generating mock dry-run=false interface=Greeter qualified-name=example/greet version=v2.10.0

打印目录结构,会发现 mocks 对象又生成了:

➜ tree
.
├── greet.go
├── greet_test.go
└── mocks
   └── Greeter.go
1 directory, 3 files
  • go.dev/blog/genera…

  • go.googlesource.com/proposal/+/…

来源:https://juejin.cn/post/7172159704674598925

标签:Go,Generate,Makefile
0
投稿

猜你喜欢

  • 利用JavaScript阻止表单提交的两种方法

    2024-04-22 22:34:44
  • Python Trie树实现字典排序

    2023-08-23 02:06:10
  • python根据照片获取地理位置及泄露防御

    2022-03-23 11:16:54
  • Python入门基本操作列表排序用法详解

    2021-01-02 15:42:02
  • 微信小程序时间轴实现方法示例

    2024-04-18 10:02:17
  • python使用装饰器和线程限制函数执行时间的方法

    2022-04-03 04:06:34
  • Vue3中defineEmits、defineProps 不用引入便直接用

    2024-05-09 09:53:01
  • JavaScript加密解密终级指南

    2008-01-03 12:25:00
  • python中如何打包用户自定义模块

    2022-12-25 11:22:53
  • Vue侦测相关api的实现方法

    2024-05-09 09:52:46
  • 跟老齐学Python之用while来循环

    2021-01-13 23:38:18
  • 元组列表字典(莫烦python基础)

    2022-03-23 09:15:58
  • python中用shutil.move移动文件或目录的方法实例

    2021-01-03 07:35:06
  • Python timeit模块原理及使用方法

    2023-09-22 08:19:18
  • 学习JavaScript设计模式之装饰者模式

    2023-07-19 08:59:07
  • 使用Python和Prometheus跟踪天气的使用方法

    2021-05-15 14:31:05
  • 爱你就要说出来,来表白吧

    2008-11-23 16:23:00
  • php开启openssl的方法

    2023-11-14 06:52:51
  • django将网络中的图片,保存成model中的ImageField的实例

    2023-12-23 01:11:33
  • 解决vue动态路由异步加载import组件,加载不到module的问题

    2024-05-29 22:45:37
  • asp之家 网络编程 m.aspxhome.com