lxy141
V2EX  ›  程序员

分享一个自己写的数据生成函数的 Go 代码生成工具---ent-factory,欢迎大家使用并提意见

By lxy141 at 2023 年 2 月 7 日 · 2208 次点击

背景

为了提升代码质量,之前给组内定了一个 UT 覆盖率的 OKR ,但 golang 写 UT 时,生成测试数据很麻烦。

一方面每个 model 实例都要手动创建,另一方面由于 golang 的语言特性每个字段也要 set 。进而,自己写 factory 函数也很麻烦,内容上都是重复的劳动。

于是自己写了一个类似于 python 中 factory-boy 的数据生成函数的代码生成工具。用来生成 factory 函数文件。

功能

  • 读取 Facebook 的 ORM 库 ent 生成的表结构目录,读取所有的表结构(也可选择读单独表)
  • 基于这结构,生成 model factory 文件
    • 内部有一个使用 faker 来 mock 数据和创建数据实例的函数
    • 可以读取默认类型、引入类型( time ,自定义 json 结构)和指针类型,生成对应的代码
    • 每个字段有一个 function optional 的函数,方便使用者自定义任意想要自定义的字段值。

分享目的

  • 觉得会有人也需要这么个工具,可以节约很多时间。
  • 功能上自己暂时没有别的想法了,希望有人在使用中发现新的需求。
  • 也许这个库有什么问题,但我自己没有使用场景来发现,可以靠大家发现。

还有更多的设置可以看该项目 Github 上的 README ,现在这个工具已经通过 makefile 成为公司项目中的一个工具包。

项目地址:https://github.com/zaihui/ent-factory

欢迎大家使用,并提意见

第 1 条附言  ·  2023 年 2 月 9 日

补充一下生成factory文件和用法

package booktableorderfactory

import (
	"github.com/bxcodec/faker"
	"github/zaihui/ent-factory/factories"
	"github/zaihui/ent-factory/gen/entschema"
	"github/zaihui/ent-factory/service/app"
)

type BookTableOrderFieldSetter func(*entschema.BookTableOrder)


func SetUID(uIDGen string) BookTableOrderFieldSetter {
	return func(bookTableOrderGen *entschema.BookTableOrder) {
		bookTableOrderGen.UID = uIDGen
	}
}

func SetUserUID(userUIDGen string) BookTableOrderFieldSetter {
	return func(bookTableOrderGen *entschema.BookTableOrder) {
		bookTableOrderGen.UserUID = userUIDGen
	}
}
func SetOrderNo(orderNoGen string) BookTableOrderFieldSetter {
	return func(bookTableOrderGen *entschema.BookTableOrder) {
		bookTableOrderGen.OrderNo = orderNoGen
	}
}
func SetType(typeGen string) BookTableOrderFieldSetter {
	return func(bookTableOrderGen *entschema.BookTableOrder) {
		bookTableOrderGen.Type = typeGen
	}
}

func New(s factories.TestSuite, opts ...BookTableOrderFieldSetter) *entschema.BookTableOrder {
	data := entschema.BookTableOrder{}
	s.NoError(faker.FakeData(&data))
	for _, opt := range opts {
		opt(&data)
	}
	return app.EntClient.BookTableOrder.Create().
		SetUID(data.UID).
		SetUserUID(data.UserUID).
		SetOrderNo(data.OrderNo).
		SetType(data.Type).
		SaveX(s.Context())
}

用法

package main
import (
	your_location_of_factories/booktableorderfactory
)
// s is an instance of test suite
order := booktableorderfactory.new(s) 
// if you want to customize the value of a field, eg. UID
order2: = booktableorderfactory.new(s, booktableorderfactory.SetUID("your uid"))
5 条回复  •  2023-02-07 14:24:06 +08:00
kindjeff
   1
kindjeff  
   2023 年 2 月 7 日
wow ,正好需要这种东西(点开发现已 star 但没看过,难崩)。

ent 的 code generation 确实是个麻烦事。
adjusted
   2
adjusted  
   2023 年 2 月 7 日
看着像用了 ent 源码改的,而不是作为 ent 的插件?
lxy141
   3
lxy141  
OP
   2023 年 2 月 7 日
@adjusted 没有用 ent 的源码,只是读了 ent 生成的 struct 。项目里的 ent 生成的内容,主要是用于测试的。
yrzs
   4
yrzs  
   2023 年 2 月 7 日
可以
lxy141
   5
lxy141  
OP
   2023 年 2 月 7 日
@kindjeff 没错,每次造数据都想吐血。。所以才写了这个。Go 又没有 Python 那么灵活,只好用 code gen 来解决问题了
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
© 2026 V2EX · 29ms · 3.9.8.5