Make it easy java

npryce / Make It Easy

Test Data Builders are described in the book Growing Object-Oriented Software, Guided by Tests by Steve Freeman and Nat Pryce. This library lets you write Test Data Builders with much less duplication and boilerplate code than the approach described in the book.

Download

You can download from Maven Central with the artifact coordinates:

Example

Consider the following class hierarchy. This hierarchy illustrates a couple of complicating factors: there is an abstract base class and there is a property (Fruit.ripeness) that is not set via the constructor but by an operation of the Fruit class.

public abstract class Fruit  private double ripeness = 0.0; public void ripen(double amount)  ripeness = Math.min(1.0, ripeness+amount); > public boolean isRipe()  return ripeness == 1.0; > > public class Apple extends Fruit  private int leaves; public Apple(int leaves)  this.leaves = leaves; > public int numberOfLeaves()  return leaves; > > public class Banana extends Fruit  public final double curve; public Banana(double curve)  this.curve = curve; > public double curve()  return curve; > > 

You can define Test Data Builders for Apples and Bananas with Make It Easy as follows:

public class FruitMakers  public static final PropertyFruit,Double> ripeness = newProperty(); public static final PropertyApple, Integer> leaves = newProperty(); public static final PropertyBanana,Double> curve = newProperty(); public static final InstantiatorApple> Apple = new InstantiatorApple>()  @Override public Apple instantiate(PropertyLookupApple> lookup)  Apple apple = new Apple(lookup.valueOf(leaves, 2)); apple.ripen(lookup.valueOf(ripeness, 0.0)); return apple; > >; public static final InstantiatorBanana> Banana = new InstantiatorBanana>()  @Override public Banana instantiate(PropertyLookupBanana> lookup)  Banana banana = new Banana(lookup.valueOf(curve, 0.5)); banana.ripen(lookup.valueOf(ripeness, 0.0)); return banana; > >; > 
MakerApple> appleWith2Leaves = an(Apple, with(2, leaves)); MakerApple> ripeApple = appleWith2Leaves.but(with(ripeness, 0.9)); MakerApple> unripeApple = appleWith2Leaves.but(with(ripeness, 0.125)); Apple apple1 = make(ripeApple); Apple apple2 = make(unripeApple); Banana defaultBanana = make(a(Banana)); Banana straightBanana = make(a(Banana, with(curve, 0.0))); Banana squishyBanana = make(a(Banana, with(ripeness, 1.0))); 

In contrast, doing so in the style documented in Growing Object-Oriented Software, Guided by Tests would look like this:

public interface BuilderT>  T build(); > public class AppleBuilder implements BuilderApple>  private double ripeness = 0.0; private int leaves = 1; private AppleBuilder() <> public static AppleBuilder anApple()  return new AppleBuilder(); > public Apple build()  Apple apple = new Apple(leaves); apple.ripen(ripeness); return apple; > public AppleBuilder withRipeness(double ripeness) this.ripeness = ripeness; return this; > public AppleBuilder withLeaves(int leaves)  this.leaves = leaves; return this; > public AppleBuilder but()  return new AppleBuilder() .withRipeness(ripeness) .withLeaves(leaves); > > public class BananaBuilder implements BuilderBanana>  private double ripeness = 0.0; private double curve = 0.5; private BananaBuilder() <> public static BananaBuilder aBanana()  return new BananaBuilder(); > public Banana build()  Banana apple = new Banana(curve); apple.ripen(ripeness); return apple; > public BananaBuilder withRipeness(double ripeness) this.ripeness = ripeness; return this; > public BananaBuilder withCurve(double curve)  this.curve = curve; return this; > public BananaBuilder but()  return new BananaBuilder() .withRipeness(ripeness) .withCurve(curve); > > 
AppleBuilder appleWith2Leaves = anApple().withLeaves(2); AppleBuilder ripeApple = appleWith2Leaves.but().withRipeness(0.9); AppleBuilder unripeApple = appleWith2Leaves.but().withRipeness(0.125); Apple apple1 = ripeApple.build(); Apple apple2 = unripeApple.build(); Banana defaultBanana = aBanana().build(); Banana straightBanana = aBanana().withCurve(0.0).build(); Banana squishyBanana = aBanana().withRipeness(1.0).build(); 

As you can see, with Make It Easy you have to write a lot less duplicated and boilerplate code. What duplication there is — in the declaration of anonymous Instantiator classes, for example — can be automatically inserted and refactored by modern IDEs. (You could also factor out calls to Fruit.ripen to a private helper method, but I left them duplicated for clarity.)

The full code for this example is in the Make It Easy repository.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].

Источник

Saved searches

Use saved searches to filter your results more quickly

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.

A tiny framework that makes it easy to write Test Data Builders in Java

npryce/make-it-easy

This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Sign In Required

Please sign in to use Codespaces.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching Xcode

If nothing happens, download Xcode and try again.

Launching Visual Studio Code

Your codespace will open once ready.

There was a problem preparing your codespace, please try again.

Latest commit

Git stats

Files

Failed to load latest commit information.

README.md

A tiny framework that makes it easy to write Test Data Builders in Java

Test Data Builders are described in the book Growing Object-Oriented Software, Guided by Tests by Steve Freeman and Nat Pryce. This library lets you write Test Data Builders with much less duplication and boilerplate code than the approach described in the book.

You can download from Maven Central with the artifact coordinates:

Consider the following class hierarchy. This hierarchy illustrates a couple of complicating factors: there is an abstract base class and there is a property (Fruit.ripeness) that is not set via the constructor but by an operation of the Fruit class.

public abstract class Fruit < private double ripeness = 0.0; public void ripen(double amount) < ripeness = Math.min(1.0, ripeness+amount); > public boolean isRipe() < return ripeness == 1.0; > > public class Apple extends Fruit < private int leaves; public Apple(int leaves) < this.leaves = leaves; > public int numberOfLeaves() < return leaves; > > public class Banana extends Fruit < public final double curve; public Banana(double curve) < this.curve = curve; > public double curve() < return curve; > >

You can define Test Data Builders for Apples and Bananas with Make It Easy as follows:

public class FruitMakers < public static final PropertyFruit,Double> ripeness = newProperty(); public static final PropertyApple, Integer> leaves = newProperty(); public static final PropertyBanana,Double> curve = newProperty(); public static final InstantiatorApple> Apple = new InstantiatorApple>() < @Override public Apple instantiate(PropertyLookupApple> lookup) < Apple apple = new Apple(lookup.valueOf(leaves, 2)); apple.ripen(lookup.valueOf(ripeness, 0.0)); return apple; > >; public static final InstantiatorBanana> Banana = new InstantiatorBanana>() < @Override public Banana instantiate(PropertyLookupBanana> lookup) < Banana banana = new Banana(lookup.valueOf(curve, 0.5)); banana.ripen(lookup.valueOf(ripeness, 0.0)); return banana; > >; >
MakerApple> appleWith2Leaves = an(Apple, with(2, leaves)); MakerApple> ripeApple = appleWith2Leaves.but(with(ripeness, 0.9)); MakerApple> unripeApple = appleWith2Leaves.but(with(ripeness, 0.125)); Apple apple1 = make(ripeApple); Apple apple2 = make(unripeApple); Banana defaultBanana = make(a(Banana)); Banana straightBanana = make(a(Banana, with(curve, 0.0))); Banana squishyBanana = make(a(Banana, with(ripeness, 1.0)));

In contrast, doing so in the style documented in Growing Object-Oriented Software, Guided by Tests would look like this:

public interface BuilderT> < T build(); > public class AppleBuilder implements BuilderApple> < private double ripeness = 0.0; private int leaves = 1; private AppleBuilder() <> public static AppleBuilder anApple() < return new AppleBuilder(); > public Apple build() < Apple apple = new Apple(leaves); apple.ripen(ripeness); return apple; > public AppleBuilder withRipeness(double ripeness)< this.ripeness = ripeness; return this; > public AppleBuilder withLeaves(int leaves) < this.leaves = leaves; return this; > public AppleBuilder but() < return new AppleBuilder() .withRipeness(ripeness) .withLeaves(leaves); > > public class BananaBuilder implements BuilderBanana> < private double ripeness = 0.0; private double curve = 0.5; private BananaBuilder() <> public static BananaBuilder aBanana() < return new BananaBuilder(); > public Banana build() < Banana apple = new Banana(curve); apple.ripen(ripeness); return apple; > public BananaBuilder withRipeness(double ripeness)< this.ripeness = ripeness; return this; > public BananaBuilder withCurve(double curve) < this.curve = curve; return this; > public BananaBuilder but() < return new BananaBuilder() .withRipeness(ripeness) .withCurve(curve); > >
AppleBuilder appleWith2Leaves = anApple().withLeaves(2); AppleBuilder ripeApple = appleWith2Leaves.but().withRipeness(0.9); AppleBuilder unripeApple = appleWith2Leaves.but().withRipeness(0.125); Apple apple1 = ripeApple.build(); Apple apple2 = unripeApple.build(); Banana defaultBanana = aBanana().build(); Banana straightBanana = aBanana().withCurve(0.0).build(); Banana squishyBanana = aBanana().withRipeness(1.0).build();

As you can see, with Make It Easy you have to write a lot less duplicated and boilerplate code. What duplication there is — in the declaration of anonymous Instantiator classes, for example — can be automatically inserted and refactored by modern IDEs. (You could also factor out calls to Fruit.ripen to a private helper method, but I left them duplicated for clarity.)

The full code for this example is in the Make It Easy repository.

Источник

Читайте также:  Команды языка html называются
Оцените статью