Go Generate 代替 Makefile使用方法详解

目录
  • 介绍
  • Mockery
  • Go Generate
    • 用法
  • 总结

介绍

图灵完备性(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

总结

Rob Pike 大神在 go generate 的提案有说过,希望 go generate 能替换 go 仓库中的 Makefile。本人没有明显的偏向,但是 go generate 确实不失为一个优秀的工具。

引用

以上就是Go Generate 代替 Makefile使用方法详解的详细内容,更多关于Go Generate代替Makefile的资料请关注我们其它相关文章!

(0)

相关推荐

  • Makefile构建Golang项目示例详解

    目录 背景 创建项目并运行 添加 Makefile 文件 Makefile 概念 变量 使用 Makefile 自动化任务 背景 构建和测试大型项目时都会很耗时,且容易出错.开发者在开发过程中需要不断执行go build.go run .go test等相关命令.还可能需要多个命令来构建不同平台的二进制文件.在正式部署时候,我们可能还需要安装一些依赖项,或者在发布之前进行代码覆盖率测试等相关前置工作. 整个过程需要很多步骤,但我们有一种简单的方法可以解决这些复杂琐碎的步骤.使用 Make 进行自

  • go使用makefile脚本编译应用的方法小结

    1. go介绍 Go官方 提供一个名为go的命令,该命令可以用来下载go的依赖,构建安装go应用,运行和测试 Go程序等等, 我们比较常用的比如go get, go mod, go run , go test等等. 但是,我们在 Go 项目中为了简化使用 go 命令的复杂性,规范团队使用 go 命令的方式,提升个人或团队的生产力,我们会使用makefile脚本,使用make来处理一些任务. 2. make及makefile makefile可以看作是make工具的脚本文件, 而make主要用来处

  • golang构建工具Makefile使用详解

    目录 正文 正文 可能是因为编译太简单了,golang 并没有一个官方的构建工具(类似于 java 的 maven 和 gradle之类的),但是除了编译,我们可能还需要下载依赖,运行测试,甚至像 easyjson,protobuf,thrift 这样的工具下载和代码生成,如果没有构建工具,这些工作就会非常麻烦 为了解决这个问题,之前写过一个 everything.sh 的脚本,把所有的操作都封装在这个脚本里面,只需要执行类似于 sh everything.sh dependency 的命令就可

  • Go项目编写Makefile规则文件概述

    目录 make介绍 Makefile介绍 Makefile文件教程解析 规则概述 示例 make介绍 借助Makefile我们在编译过程中不再需要每次手动输入编译的命令和编译的参数,可以极大简化项目编译过程. make是一个构建自动化工具,会在当前目录下寻找Makefile或makefile文件.如果存在相应的文件,它就会依据其中定义好的规则完成构建任务. Makefile介绍 我们可以把Makefile简单理解为它定义了一个项目文件的编译规则.借助Makefile我们在编译过程中不再需要每次手

  • Go Generate 代替 Makefile使用方法详解

    目录 介绍 Mockery Go Generate 用法 总结 介绍 图灵完备性(Turing completeness)是通用计算机的一个属性,它表示一个程序可以写另一个程序.比如 go test 命令:它会扫描被测试的包,写一个包含测试内容的程序,然后编译运行. 可能你听得比较多的是元编程(meta-program).这里不细究他们的区别.我们重点是,用程序生成另一个程序的场景,越来越广泛了.比如: protobufs: 根据 pb 文件(.proto)生成 go 代码文件(.pb.go)

  • JSONObject使用方法详解

    1.JSONObject介绍 JSONObject-lib包是一个beans,collections,maps,java arrays和xml和JSON互相转换的包. 2.下载jar包 http://xiazai.jb51.net/201707/yuanma/lib_jb51.rar 提供了除JSONObject的jar之外依赖的其他6个jar包,一共7个jar文件 说明:因为工作中项目用到的版本是1.1的对应jdk1.3的版本,故本篇博客是基于1.1版本介绍的. 对应此版本的javadoc下载

  • 对python 匹配字符串开头和结尾的方法详解

    1.你需要通过指定的文本模式去检查字符串的开头或者结尾,比如文件名后缀,URL Scheme 等等.检 查 字 符 串 开 头 或 结 尾 的 一 个 简 单 方 法 是 使 用str.startswith() 或 者 是str.endswith()方法.比如: >>> filename = 'spam.txt' >>> filename.endswith('.txt') True >>> filename.startswith('file:') Fa

  • Android程序打包为APK的方法详解

    Andriod安装包文件(Android Package),简称APK,后缀名为.apk. 1.生成未签名的安装包 Build -> Build Bundle(s)/APK(s) -> Build APK(s)    会生成一个未签名的apk文件,默认为debug版,可以正常安装使用. 可以 Build -> Select Build Variant -> 选择生成的apk版本(debug.release),再 Build -> Build Bundle(s)/APK(s)

  • FileZilla Server搭建FTP服务器配置及425错误与TLS警告解决方法详解

    我们为大家提供FileZilla下载链接: FileZilla 客户端:FileZilla_3.24.0_win64-setup.exe: FileZilla Server服务端绿色汉化版:FileZilla_Server-0_9_59.exe: 在服务器上安装并配置服务端: 安装过程这里不再赘述,一直下一步,在跳出弹窗时勾选"Always connect to this server",然后点击"Connect"即可(密码可自行设置或者为空): 默认安装完会有如下

  • IDEA 单元测试创建方法详解(2020.03版本亲测)

    IntelliJ IDEA创建单元测试 在 Android 中,单元测试基于 JUnit,JUnit 的平面使用足以测试完全基于 Java 代码的功能. 但是,为了测试 Android 特定的功能,您需要一堆构建在 JUnit 之上的包装类.IntelliJ IDEA 简化了 Android 测试项目构建过程中的大部分任务. 1.确保你的代码是可测试的 单元测试要求源代码的编写方式使得模块之间的依赖关系可以很容易地通过模仿来消除.另外,单元测试要求功能相互隔离. 因为这个 HelloDroid

  • Mybatis 逆向工程的三种方法详解

    Mybatis 逆向工程   逆向工程通常包括由数据库的表生成 Java 代码 和 通过 Java 代码生成数据库表.而Mybatis 逆向工程是指由数据库表生成 Java 代码.   Mybaits 需要程序员自己编写 SQL 语句,但是 Mybatis 官方提供逆向工程可以针对单表自动生成 Mybaits 执行所需要的代码,包括 POJO.Mapper.java.Mapper.xml -. 一.通过 Eclipse 插件完成 Mybatis 逆向工程 1. 在线安装 Eclipse 插件  

  • Android ListView列表优化的方法详解

    目录 前言 优化点1:使用 builder构建列表 优化点2:禁用 addAutomaticKeepAlives 和 addRepaintBoundaries 特性 优化点3:尽可能将列表元素中不变的组件使用 const 修饰 优化点4:使用 itemExtent 确定列表元素滚动方向的尺寸 优化实例 总结 前言 列表 ListView 是应用中最为常见的组件,而列表往往也会承载很多元素,当元素多,尤其是那种图片文件比较大的场合,就可能会导致列表卡顿,严重的时候可能导致应用崩溃.本篇来介绍如何优

  • Asp.net MVC scheduler的实现方法详解

    Asp.net MVC scheduler的实现方法详解 本例使用了fullcalendar js : https://fullcalendar.io/ 1. view : @{ ViewBag.Title = "Index"; Layout = "~/Views/Shared/_Layout.cshtml"; } @section PageContent{ <style> .modal-backdrop { z-index: 9; } </sty

  • shell脚本无密码登录 expect的使用方法详解

    shell脚本无密码登录 expect的使用方法详解 今天需要做一个定时任务脚本将最新的数据包文件传到远程的服务器上,虽然有密钥但也是要求输入密码的那种,所以只能另想办法实现让脚本自动输入密码了. 从网上查到使用expect可以,简单研究了一下,效果不错. 因为我的操作系统没有安装expect,所以直接"yum -y install expect",你可以根据你的操作系统安装expect,或者源码编译. 安装好之后就可以使用了,这里有几种方法: 一.单独写一个脚本 如 auto_scp

随机推荐