A simple and flexible factory pattern implementation for Go testing, inspired by factory_bot.
- Type-safe factory definitions using generics
- Automatic field population with struct tags
- Build single or multiple instances
- Sequence support for unique IDs
- Customizable field overrides
- Integration with faker for realistic test data
go get github.com/sivchari/gofab
type User struct {
ID int `gofab:"sequence"`
Name string `gofab:"name"`
Email string `gofab:"email"`
}
// Build a single user
user := gofab.Build[User]()
// Build with custom values
admin := gofab.Build[User](func(u *User) {
u.Name = "Admin User"
})
// Create 5 users with auto-generated data
users := gofab.BuildList[User](5)
// Create 3 admins with custom role
admins := gofab.BuildList[User](3, func(u *User) {
u.Role = "admin"
})
// Define a factory with defaults
userFactory := gofab.Define[User](func(u *User) {
u.Role = "user"
u.Active = true
})
// Build single instance
user := userFactory.Build()
// Build multiple instances
users := userFactory.BuildList(10)
// Override defaults
admin := userFactory.Build(func(u *User) {
u.Role = "admin"
})
gofab supports various struct tags for automatic field population:
gofab:"sequence"
- Auto-incrementing IDgofab:"name"
- Random person namegofab:"email"
- Random email addressgofab:"phone"
- Random phone numbergofab:"company"
- Random company namegofab:"address"
- Random addressgofab:"sentence:N"
- Random sentence with N wordsgofab:"word"
- Random wordgofab:"range:min,max"
- Random number in rangegofab:"-"
- Skip auto-population
func TestUserService(t *testing.T) {
// Create test data
users := gofab.BuildList[User](3)
// Test with specific scenarios
inactiveUser := gofab.Build[User](func(u *User) {
u.Active = false
})
// Your test logic here
}
type Order struct {
ID int `gofab:"sequence"`
Number string
}
order1 := gofab.Build[Order]() // ID: 1
order2 := gofab.Build[Order]() // ID: 2
order3 := gofab.Build[Order]() // ID: 3
Define named sets of attributes that can be reused:
type User struct {
Email string
Role string
Active bool
}
userFactory := gofab.Define[User]().
Trait("admin", func(u *User) {
u.Role = "admin"
u.Active = true
}).
Trait("suspended", func(u *User) {
u.Active = false
})
// Use single trait
admin := userFactory.Build(
append(userFactory.WithTrait("admin"),
func(u *User) {
u.Email = "[email protected]"
})...
)
// Combine multiple traits
suspendedAdmin := userFactory.Build(
userFactory.WithTraits("admin", "suspended")...
)
See example_test.go
for practical examples including:
- Basic usage with auto-generated data
- Using traits for test scenarios
- E-commerce product testing with discounts
MIT