{"id":16714512,"url":"https://github.com/bluele/factory-go","last_synced_at":"2025-09-09T04:39:33.210Z","repository":{"id":50314844,"uuid":"43636525","full_name":"bluele/factory-go","owner":"bluele","description":"A library for setting up Golang objects inspired by factory_bot.","archived":false,"fork":false,"pushed_at":"2023-04-05T10:47:32.000Z","size":38,"stargazers_count":373,"open_issues_count":5,"forks_count":21,"subscribers_count":10,"default_branch":"master","last_synced_at":"2024-10-13T21:05:17.124Z","etag":null,"topics":["factory-boy","factory-girl","fixtures-replacement","go","golang"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bluele.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-10-04T12:56:57.000Z","updated_at":"2024-09-26T02:01:54.000Z","dependencies_parsed_at":"2024-06-18T14:09:34.250Z","dependency_job_id":null,"html_url":"https://github.com/bluele/factory-go","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluele%2Ffactory-go","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluele%2Ffactory-go/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluele%2Ffactory-go/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluele%2Ffactory-go/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bluele","download_url":"https://codeload.github.com/bluele/factory-go/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247332555,"owners_count":20921853,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["factory-boy","factory-girl","fixtures-replacement","go","golang"],"created_at":"2024-10-12T21:05:30.789Z","updated_at":"2025-04-05T12:01:32.130Z","avatar_url":"https://github.com/bluele.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# factory-go\n\n![Test](https://github.com/bluele/factory-go/workflows/Test/badge.svg)\n[![GoDoc](https://godoc.org/github.com/bluele/factory-go?status.svg)](https://pkg.go.dev/github.com/bluele/factory-go?tab=doc)\n\nfactory-go is a fixtures replacement inspired by [factory_boy](https://github.com/FactoryBoy/factory_boy) and [factory_bot](https://github.com/thoughtbot/factory_bot).\n\nIt can be generated easily complex objects by using this, and maintain easily those objects generaters.\n\n## Install\n\n```\n$ go get -u github.com/bluele/factory-go/factory\n```\n\n## Usage\n\nAll of the following code on [examples](https://github.com/bluele/factory-go/tree/master/examples).\n\n* [Define a simple factory](https://github.com/bluele/factory-go#define-a-simple-factory)\n* [Use factory with random yet realistic values](https://github.com/bluele/factory-go#use-factory-with-random-yet-realistic-values)\n* [Define a factory includes sub-factory](https://github.com/bluele/factory-go#define-a-factory-includes-sub-factory)\n* [Define a factory includes a slice for sub-factory](https://github.com/bluele/factory-go#define-a-factory-includes-a-slice-for-sub-factory)\n* [Define a factory includes sub-factory that contains self-reference](https://github.com/bluele/factory-go#define-a-factory-includes-sub-factory-that-contains-self-reference)\n* [Define a sub-factory refers to parent factory](https://github.com/bluele/factory-go#define-a-sub-factory-refers-to-parent-factory)\n\n### Define a simple factory\n\nDeclare an factory has a set of simple attribute, and generate a fixture object.\n\n```go\npackage main\n\nimport (\n  \"fmt\"\n  \"github.com/bluele/factory-go/factory\"\n)\n\ntype User struct {\n  ID       int\n  Name     string\n  Location string\n}\n\n// 'Location: \"Tokyo\"' is default value.\nvar UserFactory = factory.NewFactory(\n  \u0026User{Location: \"Tokyo\"},\n).SeqInt(\"ID\", func(n int) (interface{}, error) {\n  return n, nil\n}).Attr(\"Name\", func(args factory.Args) (interface{}, error) {\n  user := args.Instance().(*User)\n  return fmt.Sprintf(\"user-%d\", user.ID), nil\n})\n\nfunc main() {\n  for i := 0; i \u003c 3; i++ {\n    user := UserFactory.MustCreate().(*User)\n    fmt.Println(\"ID:\", user.ID, \" Name:\", user.Name, \" Location:\", user.Location)\n  }\n}\n```\n\nOutput:\n\n```\nID: 1  Name: user-1  Location: Tokyo\nID: 2  Name: user-2  Location: Tokyo\nID: 3  Name: user-3  Location: Tokyo\n```\n\n### Use factory with random yet realistic values.\n\nTests look better with random yet realistic values. For example, you can use [go-randomdata](https://github.com/Pallinder/go-randomdata) library to get them:\n\n```go\npackage main\n\nimport (\n  \"fmt\"\n  \"github.com/Pallinder/go-randomdata\"\n  \"github.com/bluele/factory-go/factory\"\n)\n\ntype User struct {\n  ID       int\n  Name     string\n  Location string\n}\n\n// 'Location: \"Tokyo\"' is default value.\nvar UserFactory = factory.NewFactory(\n  \u0026User{},\n).SeqInt(\"ID\", func(n int) (interface{}, error) {\n  return n, nil\n}).Attr(\"Name\", func(args factory.Args) (interface{}, error) {\n  return randomdata.FullName(randomdata.RandomGender), nil\n}).Attr(\"Location\", func(args factory.Args) (interface{}, error) {\n  return randomdata.City(), nil\n})\n\nfunc main() {\n  for i := 0; i \u003c 3; i++ {\n    user := UserFactory.MustCreate().(*User)\n    fmt.Println(\"ID:\", user.ID, \" Name:\", user.Name, \" Location:\", user.Location)\n  }\n}\n```\n\nOutput:\n\n```\nID: 1  Name: Benjamin Thomas  Location: Burrton\nID: 2  Name: Madison Davis  Location: Brandwell\nID: 3  Name: Aubrey Robinson  Location: Campden\n```\n\n### Define a factory includes sub-factory\n\n```go\npackage main\n\nimport (\n  \"fmt\"\n  \"github.com/bluele/factory-go/factory\"\n)\n\ntype Group struct {\n  ID   int\n  Name string\n}\n\ntype User struct {\n  ID       int\n  Name     string\n  Location string\n  Group    *Group\n}\n\nvar GroupFactory = factory.NewFactory(\n  \u0026Group{},\n).SeqInt(\"ID\", func(n int) (interface{}, error) {\n  return 2 - n%2, nil\n}).Attr(\"Name\", func(args factory.Args) (interface{}, error) {\n  group := args.Instance().(*Group)\n  return fmt.Sprintf(\"group-%d\", group.ID), nil\n})\n\n// 'Location: \"Tokyo\"' is default value.\nvar UserFactory = factory.NewFactory(\n  \u0026User{Location: \"Tokyo\"},\n).SeqInt(\"ID\", func(n int) (interface{}, error) {\n  return n, nil\n}).Attr(\"Name\", func(args factory.Args) (interface{}, error) {\n  user := args.Instance().(*User)\n  return fmt.Sprintf(\"user-%d\", user.ID), nil\n}).SubFactory(\"Group\", GroupFactory)\n\nfunc main() {\n  for i := 0; i \u003c 3; i++ {\n    user := UserFactory.MustCreate().(*User)\n    fmt.Println(\n      \"ID:\", user.ID, \" Name:\", user.Name, \" Location:\", user.Location,\n      \" Group.ID:\", user.Group.ID, \" Group.Name\", user.Group.Name)\n  }\n}\n```\n\nOutput:\n\n```\nID: 1  Name: user-1  Location: Tokyo  Group.ID: 1  Group.Name group-1\nID: 2  Name: user-2  Location: Tokyo  Group.ID: 2  Group.Name group-2\nID: 3  Name: user-3  Location: Tokyo  Group.ID: 1  Group.Name group-1\n```\n\n### Define a factory includes a slice for sub-factory.\n\n```go\npackage main\n\nimport (\n  \"fmt\"\n  \"github.com/bluele/factory-go/factory\"\n)\n\ntype Post struct {\n  ID      int\n  Content string\n}\n\ntype User struct {\n  ID    int\n  Name  string\n  Posts []*Post\n}\n\nvar PostFactory = factory.NewFactory(\n  \u0026Post{},\n).SeqInt(\"ID\", func(n int) (interface{}, error) {\n  return n, nil\n}).Attr(\"Content\", func(args factory.Args) (interface{}, error) {\n  post := args.Instance().(*Post)\n  return fmt.Sprintf(\"post-%d\", post.ID), nil\n})\n\nvar UserFactory = factory.NewFactory(\n  \u0026User{},\n).SeqInt(\"ID\", func(n int) (interface{}, error) {\n  return n, nil\n}).Attr(\"Name\", func(args factory.Args) (interface{}, error) {\n  user := args.Instance().(*User)\n  return fmt.Sprintf(\"user-%d\", user.ID), nil\n}).SubSliceFactory(\"Posts\", PostFactory, func() int { return 3 })\n\nfunc main() {\n  for i := 0; i \u003c 3; i++ {\n    user := UserFactory.MustCreate().(*User)\n    fmt.Println(\"ID:\", user.ID, \" Name:\", user.Name)\n    for _, post := range user.Posts {\n      fmt.Printf(\"\\tPost.ID: %v  Post.Content: %v\\n\", post.ID, post.Content)\n    }\n  }\n}\n```\n\nOutput:\n\n```\nID: 1  Name: user-1\n        Post.ID: 1  Post.Content: post-1\n        Post.ID: 2  Post.Content: post-2\n        Post.ID: 3  Post.Content: post-3\nID: 2  Name: user-2\n        Post.ID: 4  Post.Content: post-4\n        Post.ID: 5  Post.Content: post-5\n        Post.ID: 6  Post.Content: post-6\nID: 3  Name: user-3\n        Post.ID: 7  Post.Content: post-7\n        Post.ID: 8  Post.Content: post-8\n        Post.ID: 9  Post.Content: post-9\n```\n\n### Define a factory includes sub-factory that contains self-reference.\n\n```go\npackage main\n\nimport (\n  \"fmt\"\n  \"github.com/Pallinder/go-randomdata\"\n  \"github.com/bluele/factory-go/factory\"\n)\n\ntype User struct {\n  ID          int\n  Name        string\n  CloseFriend *User\n}\n\nvar UserFactory = factory.NewFactory(\n  \u0026User{},\n)\n\nfunc init() {\n  UserFactory.SeqInt(\"ID\", func(n int) (interface{}, error) {\n    return n, nil\n  }).Attr(\"Name\", func(args factory.Args) (interface{}, error) {\n    return randomdata.FullName(randomdata.RandomGender), nil\n  }).SubRecursiveFactory(\"CloseFriend\", UserFactory, func() int { return 2 }) // recursive depth is always 2\n}\n\nfunc main() {\n  user := UserFactory.MustCreate().(*User)\n  fmt.Println(\"ID:\", user.ID, \" Name:\", user.Name,\n    \" CloseFriend.ID:\", user.CloseFriend.ID, \" CloseFriend.Name:\", user.CloseFriend.Name)\n  // `user.CloseFriend.CloseFriend.CloseFriend ` depth is 3, so this value is always nil.\n  fmt.Printf(\"%v %v\\n\", user.CloseFriend.CloseFriend, user.CloseFriend.CloseFriend.CloseFriend)\n}\n```\n\nOutput:\n```\nID: 1  Name: Mia Williams  CloseFriend.ID: 2  CloseFriend.Name: Joseph Wilson\n\u0026{3 Liam Wilson \u003cnil\u003e} \u003cnil\u003e\n```\n\n### Define a sub-factory refers to parent factory\n\n```go\npackage main\n\nimport (\n  \"fmt\"\n  \"github.com/bluele/factory-go/factory\"\n)\n\ntype User struct {\n  ID    int\n  Name  string\n  Group *Group\n}\n\ntype Group struct {\n  ID    int\n  Name  string\n  Users []*User\n}\n\nvar UserFactory = factory.NewFactory(\n  \u0026User{},\n).SeqInt(\"ID\", func(n int) (interface{}, error) {\n  return n, nil\n}).Attr(\"Name\", func(args factory.Args) (interface{}, error) {\n  user := args.Instance().(*User)\n  return fmt.Sprintf(\"user-%d\", user.ID), nil\n}).Attr(\"Group\", func(args factory.Args) (interface{}, error) {\n  if parent := args.Parent(); parent != nil {\n    // if args have parent, use it.\n    return parent.Instance(), nil\n  }\n  return nil, nil\n})\n\nvar GroupFactory = factory.NewFactory(\n  \u0026Group{},\n).SeqInt(\"ID\", func(n int) (interface{}, error) {\n  return 2 - n%2, nil\n}).Attr(\"Name\", func(args factory.Args) (interface{}, error) {\n  group := args.Instance().(*Group)\n  return fmt.Sprintf(\"group-%d\", group.ID), nil\n}).SubSliceFactory(\"Users\", UserFactory, func() int { return 3 })\n\nfunc main() {\n  group := GroupFactory.MustCreate().(*Group)\n  fmt.Println(\"Group.ID:\", group.ID)\n  for _, user := range group.Users {\n    fmt.Println(\"\\tUser.ID:\", user.ID, \" User.Name:\", user.Name, \" User.Group.ID:\", user.Group.ID)\n  }\n}\n```\n\nOutput:\n```\nGroup.ID: 1\n        User.ID: 1  User.Name: user-1  User.Group.ID: 1\n        User.ID: 2  User.Name: user-2  User.Group.ID: 1\n        User.ID: 3  User.Name: user-3  User.Group.ID: 1\n```\n\n## Persistent models\n\nCurrently this project has no support for directly integration with ORM like [gorm](https://github.com/jinzhu/gorm), so you need to do manually.\n\nHere is an example: https://github.com/bluele/factory-go/blob/master/examples/gorm_integration.go\n\n# Author\n\n**Jun Kimura**\n\n* \u003chttp://github.com/bluele\u003e\n* \u003cjunkxdev@gmail.com\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbluele%2Ffactory-go","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbluele%2Ffactory-go","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbluele%2Ffactory-go/lists"}