Coder Social home page Coder Social logo

beanmother's Introduction

Beanmother

Maven Central Build Status Coverage Status Javadocs License

image

Beanmother helps to create your various and complex objects super easily with fixtures for testing. It encourages developers to write more tests.

Beanmother is a implementation of ObjectMother 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 types of test. You can use a your bean as it is.

Java 7 and above are supported.

Example

Create fixture .yml file in test/resources/fixtures as a convention.

# test/resources/fixtures/publishing.yml

book: &book
  title: ${faker.book.title}
  language: en
  publishedAt: ${faker.date.between('2000-01-01', '2010-01-01')}

author:
  id: ${sequence.number}
  name: ${faker.book.author}
  introduction: ${faker.lorem.paragraph}
  birth: ${faker.date.between('1990-01-01', '2000-01-01')}
  gender: MALE
  works:
    - <<: *book
    - <<: *book
    - <<: *book

YAML format is very easy to read and write. It is expressive and extensible. You can use scripts provided by Beanmother to create multiple types of random data and global sequentail numbers.

ObjectMother objectMother = ObjectMother.getInstance();

@Test
public void testSingleObject() {
    Book book = objectMother.bear("book", Book.class);
    Author author = objectMother.bear("author", Author.class);    
}

@Test
public void testMultipleObjects() {
    List<Author> authors = objectMother.bear("author", Author.class, 10);
}

And just create!

Usage

Installation

  • Apache Maven
<dependency>
    <groupId>io.beanmother</groupId>
    <artifactId>beanmother-core</artifactId>
    <version>0.7.3</version>
    <scope>test</scope>
</dependency>
  • Gradle
testCompile 'io.beanmother:beanmother-core:0.7.3'

Extensions

  • For java8 time and optional data type
<dependency>
    <groupId>io.beanmother</groupId>
    <artifactId>beanmother-java8-converter</artifactId>
    <version>0.7.3</version>
    <scope>test</scope>
</dependency>
testCompile 'io.beanmother:beanmother-java8-converter:0.7.3'
  • For Joda-time data type
<dependency>
    <groupId>io.beanmother</groupId>
    <artifactId>beanmother-joda-time-converter</artifactId>
    <version>0.7.3</version>
    <scope>test</scope>
</dependency>
testCompile 'io.beanmother:beanmother-joda-time-converter:0.7.3'

Fixture Script

The scripts provided by Beanmother is a kind of fake property value generator.

author:
  title: ${faker.book.title}

Currently, FakerScriptRunner and SeqenceScriptRunner are registered as a default.

  • FakerScriptRunner works with faker namespace. the script runner is implemented by java-faker. you can find a usage of java-faker in document. If a method has no arguments, you can ignore parentheses. for example,
beer:
  hop: ${faker.beer.hop}
  malt: ${faker.beer.malt}
  created_at: ${faker.date.between('1990-01-01', '2000-01-01')}
  • SequenceScriptRunner works with sequence namespace. the script generate sequential number globally. for example,
person:
  id: ${sequence.number}

Arguments constructor bean

If a bean does not have no-argument contructor, just add _construct key. for example,

price:
  _construct:
    - 3
    - USD

PostProcessor

If you need to common configuration for specific beans, you can use PostProcessor.

Customization

ObjectMother class is a default implementation of AbstractBeanMother class. For customization, simply extend AbstractBeanMother. Highly recommended to build as a singleton instance.

public class MyObjectMother extends AbstractBeanMother {

    private static MyObjectMother myObjectMother = new MyObjectMother();

    private MyObjectMother() {
        super();
    }


    // Override for adding your default fixture directory paths
    @Override
    public String[] defaultFixturePaths() {
        return new String[]{ 'test-models', 'fixtures' };
    }

    // Override for adding your custom Converter.
    @Override
    protected void configureConverterFactory(ConverterFactory converterFactory) {
        converterFactory.register(new MyConverter());
    }

    // Override for adding your custom ScriptRunner.
    @Override
    protected void configureScriptHandler(ScriptHandler scriptHandler) {
        scriptHandler.register(new MyScriptRunner);     
    }

    // Override for adding your custom PostProcessor.
    @Override
    protected void configurePostProcessorFactory(PostProcessorFactory postProcessorFactory) {
        postProcessorFactory.register(new MyPostProcessor);
    }
}

Register PostProcessors

A PostProcessor can handle you bean after mapper.

public class AuthorPostProcessor extends PostProcessor<Author> {
    @Override
    public void process(Author bean, FixtureMap fixtureMap) {
        for(Book book : bean.getWorks()) {
            book.setAuthor(bean);
        }
    }
}

And pass the instance as a argument when you create a instance.

Author author = ObjectMother.bear("author", Author.class, new AuthorPostProcessor());

or, register the PostProcessor to your custom BeanMother for using globally.

@Override
protected void configurePostProcessorFactory(PostProcessorFactory postProcessorFactory) {
    postProcessorFactory.register(new AuthorPostProcessor());
}

Everytime you create a instance of Author, AuthorPostProcessor will run before return a instance of Author.

Customize default fixture path.

Just register the path in ObjectMother. It wil scan all files under the path.

ObjectMother.addFixtureLocation("mocks");

Or, override #defaultFixturePaths in your custom BeanMother.

@Override
public String[] defaultFixturePaths() {
    // Add your fixture directory or file paths under `resources`.
    return new String[]{ 'test-models', 'fixtures' };
}

Customize converter

You can write your own converter for some reason.

public class MyIntegerToStringConverter extends AbstractGenericConverter<Integer, String> {
    @Override
    public String convert(Integer source) {
        return String.valueOf(source + 1);
    }
}

And, register the Converter in your custom BeanMother.

@Override
protected void configureConverterFactory(ConverterFactory converterFactory) {
    converterFactory.register(new MyIntegerToStringConverter());
}

Customize ScriptRunner

You can write your own ScriptRunner

public class MyScriptRunner implements ScriptRunner {

    @Override
    public Object run(ScriptFragment scriptFragment) {
		    // Do something
        return any;
    }

    @Override
    public boolean canHandle(ScriptFragment scriptFragment) {
        return scriptFragment.getMethodName.equal("myname");
    }
}

And, register the ScriptRunner in your custom BeanMother.

@Override
protected void configureScriptHandler(ScriptHandler scriptHandler) {
    scriptHandler.register(new MyScriptRunner());     
}

Contributions

Any kind of contributions are very welcome! Coding style guideline is not prepared yet. Although I use Intellij IDE default style, follow a common sense you believe. But please 4 space indentation.

beanmother's People

Contributors

keepcosmos avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.