I want to have an easy way to construct test data and have found the Builder pattern to be a good fit as described here. However to reduce boilerplate codes in the component tests, even more, I have found @Builder from Project Lombok to be a nice candidate to try. However, I can't find any documentation or online examples on how to use it on a method. I want to use @Builder
on some sort of factory method since I can't make any changes to the implementation.
Can someone give an example on how to actually use @Builder
on a method?
The @Builder annotation produces complex builder APIs for your classes. @Builder lets you automatically produce the code required to have your class be instantiable with code such as: Person. builder()
Lombok's @Builder annotation is a useful technique to implement the builder pattern that aims to reduce the boilerplate code. In this tutorial, we will learn to apply @Builder to a class and other useful features. Ensure you have included Lombok in the project and installed Lombok support in the IDE.
The builder pattern allows you to enforce a step-by-step process to construct a complex object as a finished product. In this pattern, the step-by-step construction process remains same but the finished products can have different representations.
The @SuperBuilder annotation produces complex builder APIs for your classes. In contrast to @Builder , @SuperBuilder also works with fields from superclasses. However, it only works for types. Most importantly, it requires that all superclasses also have the @SuperBuilder annotation.
This is how you use @Builder.
//Employee.Java import lombok.Builder; import lombok.ToString; @Builder @ToString public class Employee { private final String empName; private final int salary; } // Main.java public class Main { public static void main(String[] args) { Employee emp = Employee.builder().empName("Deendaya").salary(100).build(); System.out.println(emp); } }
Using @Builder
on method to create a Dog
and Cat
instance.
In this example @Value
creates a final immutable value object with accessor methods (getters), an all args constructor, equals()
, hashCode()
and toString()
.
import static org.junit.Assert.*; import lombok.Builder; import lombok.Value; import org.junit.Test; @SuppressWarnings("javadoc") public class ImmutableAnimals { @Builder(builderMethodName = "dogBuilder") public static Dog newDog(String color, String barkSound) { return new Dog(color, barkSound); } @Builder(builderMethodName = "catBuilder") public static Cat newCat(String color, String meowSound) { return new Cat(color, meowSound); } public static interface Animal { String getColor(); } @Value public static class Cat implements Animal { String color; String meowSound; } @Value public static class Dog implements Animal { String color; String barkSound; } @Test public void testDog() { final String expectedBarkSound = "woof"; final String expectedColor = "brown"; final Dog dog = ImmutableAnimals.dogBuilder() .barkSound(expectedBarkSound) .color(expectedColor) .build(); assertEquals(expectedBarkSound, dog.getBarkSound()); assertEquals(expectedColor, dog.getColor()); } @Test public void testCat() { final String expectedMeowSound = "purr"; final String expectedColor = "white"; final Cat cat = ImmutableAnimals.catBuilder() .meowSound(expectedMeowSound) .color(expectedColor) .build(); assertEquals(expectedMeowSound, cat.getMeowSound()); assertEquals(expectedColor, cat.getColor()); } }
Here's another example with the same domain classes but using mutable values. However, as always favor immutability whenever possible.
import static org.junit.Assert.*; import lombok.Builder; import lombok.Data; import org.junit.Test; @SuppressWarnings("javadoc") public class MutableAnimals { @Builder(builderMethodName = "dogBuilder") public static Dog newDog(String color, String barkSound) { final Dog dog = new Dog(); dog.setBarkSound(barkSound); dog.setColor(color); return dog; } @Builder(builderMethodName = "catBuilder") public static Cat newCat(String color, String meowSound) { final Cat cat = new Cat(); cat.setMeowSound(meowSound); cat.setColor(color); return cat; } public static interface Animal { String getColor(); } @Data public static class Cat implements Animal { String color; String meowSound; } @Data public static class Dog implements Animal { String color; String barkSound; } @Test public void testDog() { final String expectedBarkSound = "woof"; final String expectedColor = "brown"; final Dog dog = MutableAnimals.dogBuilder() .barkSound(expectedBarkSound) .color(expectedColor) .build(); assertEquals(expectedBarkSound, dog.getBarkSound()); assertEquals(expectedColor, dog.getColor()); } @Test public void testCat() { final String expectedMeowSound = "purr"; final String expectedColor = "white"; final Cat cat = MutableAnimals.catBuilder() .meowSound(expectedMeowSound) .color(expectedColor) .build(); assertEquals(expectedMeowSound, cat.getMeowSound()); assertEquals(expectedColor, cat.getColor()); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With