{"id":25776498,"url":"https://github.com/keepcosmos/beanmother","last_synced_at":"2026-01-11T16:54:01.508Z","repository":{"id":50080587,"uuid":"100366560","full_name":"keepcosmos/beanmother","owner":"keepcosmos","description":"A library for setting up Java objects as test data.","archived":false,"fork":false,"pushed_at":"2022-12-14T20:49:38.000Z","size":697,"stargazers_count":113,"open_issues_count":13,"forks_count":23,"subscribers_count":7,"default_branch":"master","last_synced_at":"2024-05-03T00:16:40.670Z","etag":null,"topics":["bean","factories","faker","fixtures","hacktoberfest","java","object-mapping","test-automation","test-driven-development","testing","testing-tools"],"latest_commit_sha":null,"homepage":"http://beanmother.io","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/keepcosmos.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}},"created_at":"2017-08-15T10:26:57.000Z","updated_at":"2024-03-31T14:19:49.000Z","dependencies_parsed_at":"2023-01-29T00:55:14.234Z","dependency_job_id":null,"html_url":"https://github.com/keepcosmos/beanmother","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keepcosmos%2Fbeanmother","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keepcosmos%2Fbeanmother/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keepcosmos%2Fbeanmother/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keepcosmos%2Fbeanmother/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/keepcosmos","download_url":"https://codeload.github.com/keepcosmos/beanmother/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240987435,"owners_count":19889334,"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":["bean","factories","faker","fixtures","hacktoberfest","java","object-mapping","test-automation","test-driven-development","testing","testing-tools"],"created_at":"2025-02-27T06:01:25.567Z","updated_at":"2026-01-11T16:54:01.502Z","avatar_url":"https://github.com/keepcosmos.png","language":"Java","readme":"# Beanmother \n\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.beanmother/beanmother-core/badge.svg)](https://search.maven.org/#search%7Cga%7C1%7Cio.beanmother)\n[![Build Status](https://travis-ci.org/keepcosmos/beanmother.svg?branch=master)](https://travis-ci.org/keepcosmos/beanmother)\n[![Coverage Status](https://coveralls.io/repos/github/keepcosmos/beanmother/badge.svg?branch=master)](https://coveralls.io/github/keepcosmos/beanmother?branch=master)\n[![Javadocs](http://javadoc.io/badge/io.beanmother/beanmother-core.svg)](http://javadoc.io/doc/io.beanmother/beanmother-core)\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)  \n\n\n![beanmother](logo.png) \n\n**Beanmother** helps to create various objects, simple and complex, super easily with fixtures for testing. It encourages developers to write more tests.\n\nBeanmother is an implementation of [ObjectMother](https://martinfowler.com/bliki/ObjectMother.html) pattern and also fixture replacement tool. You do not need to write extra code(like factories or builders) for creating test objects. Beanmother helps to create fresh and randomized bean objects for every type of test. You can use a bean as is!.\n\nJava 7 and above are supported.\n\n## Example\n\nCreate fixture `.yml` file in `test/resources/fixtures` as a convention.\n\n```yaml\n# test/resources/fixtures/publishing.yml\n\nbook: \u0026book\n  title: ${faker.book.title}\n  language: en\n  publishedAt: ${faker.date.between('2000-01-01', '2010-01-01')}\n\nauthor:\n  id: ${sequence.number}\n  name: Ernest Hemingway\n  introduction: ${faker.lorem.paragraph}\n  birth: July 21, 1899\n  gender: MALE\n  works:\n    - \u003c\u003c: *book\n    - \u003c\u003c: *book\n    - \u003c\u003c: *book\n```\n\n[YAML format](http://yaml.org/spec/1.1/) is very easy to read and write. It is expressive and extensible as well. You can use scripts provided by Beanmother to create multiple types of random data and global sequential numbers.\n\n\n```java\n\nObjectMother objectMother = ObjectMother.getInstance();\n\n@Test\npublic void testSingleObject() {\n    Book book = objectMother.bear(\"book\", Book.class);\n    Author author = objectMother.bear(\"author\", Author.class);    \n}\n\n@Test\npublic void testMultipleObjects() {\n    List\u003cAuthor\u003e authors = objectMother.bear(\"author\", Author.class, 10);\n}\n\n```\n\nAnd just create!\n\nBut if for some reason, you need load the fixtures from another directory inside the classpath\n\n```java\nobjectMother.addFixtureLocation(\"another_dir\") // test/resources/another_dir\n```\n\nAnd if the directory it's outside classpath\n\n```java\nobjectMother.addFixtureLocation(\"filesystem:///absolute/path/to/fixture/dir\") // /absolute/path/to/fixture/dir \n```\n\n## Usage\n* [Installation](#installation)\n* [Fixture Script](#fixture-script)\n* [Arguments-constructor bean](#arguments-constructor-bean)\n* [Post Processor](#postprocessor)\n* [Customization](#customization)\n\n\n### Installation\n\n* Apache Maven\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.beanmother\u003c/groupId\u003e\n    \u003cartifactId\u003ebeanmother-core\u003c/artifactId\u003e\n    \u003cversion\u003e0.9.0\u003c/version\u003e\n    \u003cscope\u003etest\u003c/scope\u003e\n\u003c/dependency\u003e\n```\n\n- Gradle\n\n```groovy\ntestCompile 'io.beanmother:beanmother-core:0.9.0'\n```\n\n#### Extensions\n\n* [beanmother-java8-converter](https://search.maven.org/#artifactdetails|io.beanmother|beanmother-java8-converter|0.9.0|jar) - For java8 time and optional data type\n\n* [beanmother-joda-time-converter](https://search.maven.org/#artifactdetails|io.beanmother|beanmother-joda-time-converter|0.9.0|jar) - For Joda-time data type\n\n* [beanmother-guava-converter](https://search.maven.org/#artifactdetails|io.beanmother|beanmother-guava-converter|0.9.0|jar) - For Google Guava optional data type\n\n* [beanmother-builder-converter](https://search.maven.org/#artifactdetails|io.beanmother|beanmother-builder-converter|0.9.0|jar) - For builder pattern initializer\n\n\n### Fixture Script\n\nThe scripts provided by Beanmother are kind of fake property value generators.\n\n```yml\nauthor:\n  title: ${faker.book.title}\n```\n\nCurrently, `FakerScriptRunner` and `SeqenceScriptRunner` are registered as a default.\n\n* `FakerScriptRunner` works with `faker` namespace. The script runner is implemented by [java-faker](https://github.com/DiUS/java-faker). You can find a usage of java-faker in [this document](http://dius.github.io/java-faker/apidocs/index.html). If a method has no arguments, parentheses can be ignored. For example,\n\n```yaml\nbeer:\n  hop: ${faker.beer.hop}\n  malt: ${faker.beer.malt}\n  created_at: ${faker.date.between('1990-01-01', '2000-01-01')}\n```\n\n* `SequenceScriptRunner` works with the `sequence` namespace. The script generates sequential numbers globally. For example,\n\n```yaml\nperson:\n  id: ${sequence.number}\n```\n\n\n\n###  Arguments constructor bean\n\nIf a bean does not have a no-argument contructor, just add `_construct` key. For example,\n\n```yaml\nprice:\n  _construct:\n    - 3\n    - USD\n```\n\n\n### PostProcessor\n\nIf you need a common configuration for specific beans, you can use [PostProcessor](#register-post-processors).\n\n\n## Customization\n\n`ObjectMother` class is a default implementation of `AbstractBeanMother` class. For customization, simply extend `AbstractBeanMother`. I highly recommend building it as a singleton instance.\n\n```java\npublic class MyObjectMother extends AbstractBeanMother {\n\n    private static MyObjectMother myObjectMother = new MyObjectMother();\n\n    private MyObjectMother() {\n        super();\n    }\n\n\n    // Override for adding your default fixture directory paths.\n    @Override\n    public String[] defaultFixturePaths() {\n        return new String[]{ 'test-models', 'fixtures' };\n    }\n\n    // Override for adding your custom Converter.\n    @Override\n    protected void configureConverterFactory(ConverterFactory converterFactory) {\n        converterFactory.register(new MyConverter());\n    }\n\n    // Override for adding your custom ScriptRunner.\n    @Override\n    protected void configureScriptHandler(ScriptHandler scriptHandler) {\n        scriptHandler.register(new MyScriptRunner);     \n    }\n\n    // Override for adding your custom PostProcessor.\n    @Override\n    protected void configurePostProcessorFactory(PostProcessorFactory postProcessorFactory) {\n        postProcessorFactory.register(new MyPostProcessor);\n    }\n}\n```\n\n#### Register PostProcessors\n\nA PostProcessor can handle your bean after mapper.\n\n```java\npublic class AuthorPostProcessor extends PostProcessor\u003cAuthor\u003e {\n    @Override\n    public void process(Author bean, FixtureMap fixtureMap) {\n        for(Book book : bean.getWorks()) {\n            book.setAuthor(bean);\n        }\n    }\n}\n```\n\nAnd, pass the instance as an argument when you create an instance.\n\n```java\nAuthor author = ObjectMother.bear(\"author\", Author.class, new AuthorPostProcessor());\n```\n\nor, register the PostProcessor to your custom BeanMother for using it globally.\n\n```java\n@Override\nprotected void configurePostProcessorFactory(PostProcessorFactory postProcessorFactory) {\n    postProcessorFactory.register(new AuthorPostProcessor());\n}\n```\n\nEverytime you create an instance of Author, `AuthorPostProcessor` will run before returning an instance of Author.\n\n#### Customize default fixture path.\n\nJust register the path in ObjectMother. It will scan all files under the path.\n\n```java\nObjectMother.addFixtureLocation(\"mocks\");\n```\n\nOr, override `#defaultFixturePaths` in your custom BeanMother.\n\n```java\n@Override\npublic String[] defaultFixturePaths() {\n    // Add your fixture directory or file paths under `resources`.\n    return new String[]{ 'test-models', 'fixtures' };\n}\n```  \n\n\n#### Customize converter\n\nYou can write your own converter if you want to.\n\n```java\npublic class MyIntegerToStringConverter extends AbstractGenericConverter\u003cInteger, String\u003e {\n    @Override\n    public String convert(Integer source) {\n        return String.valueOf(source + 1);\n    }\n}\n```\n\nAnd, register the converter in your custom BeanMother.\n\n```java\n@Override\nprotected void configureConverterFactory(ConverterFactory converterFactory) {\n    converterFactory.register(new MyIntegerToStringConverter());\n}\n```\n\n#### Customize ScriptRunner\n\nYou can write your own ScriptRunner.\n\n```java\npublic class MyScriptRunner implements ScriptRunner {\n\n    @Override\n    public Object run(ScriptFragment scriptFragment) {\n\t\t    // Do something\n        return any;\n    }\n\n    @Override\n    public boolean canHandle(ScriptFragment scriptFragment) {\n        return scriptFragment.getMethodName.equal(\"myname\");\n    }\n}\n```\n\nAnd, register the ScriptRunner in your custom BeanMother.\n\n```java\n@Override\nprotected void configureScriptHandler(ScriptHandler scriptHandler) {\n    scriptHandler.register(new MyScriptRunner());     \n}\n```\n\n## Tests\n\n```\n$ mvn test\n```\n\n## Contributions\n\nAny kind of contributions are very welcome! Coding style guideline is not prepared yet. Although I use Intellij IDE default style, follow common sense and please use four-space indentation.\n","funding_links":[],"categories":["Projects","Solutions","测试","项目"],"sub_categories":["Testing","测试"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkeepcosmos%2Fbeanmother","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkeepcosmos%2Fbeanmother","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkeepcosmos%2Fbeanmother/lists"}