object-mother/README.md
The Object Mother pattern simplifies the creation of objects for testing purposes in Java, ensuring that test cases are clear and maintainable by centralizing the logic needed to instantiate objects in a consistent state.
Real-world example
Imagine you're developing a Java application for a travel agency. In your system, there are different types of travelers, such as tourists, business travelers, and travel agents, each with specific attributes and behaviors. To perform thorough testing, you need to create and manipulate these traveler objects in various contexts. The Object Mother Pattern can help you generate consistent and predefined traveler objects for testing purposes, ensuring that your tests are based on known, reliable data.
In plain words
The Object Mother Pattern is a design pattern used in Java to simplify the creation of objects with specific configurations, especially for testing. Instead of manually constructing objects with varying properties for each test case, you create a dedicated "Object Mother" class or method that produces these objects with predefined settings. This ensures that you have consistent and predictable test data, making your tests more reliable and easier to manage.
wiki.c2.com says
Object Mother starts with the factory pattern, by delivering prefabricated test-ready objects via a simple method call. It moves beyond the realm of the factory by
- facilitating the customization of created objects,
- providing methods to update the objects during the tests, and
- if necessary, deleting the object from the database at the completion of the test.
Mind map
Flowchart
The Object Mother is a design pattern that aims to provide an easy way to create objects for testing purposes. It encapsulates the logic for building instances of complex objects in one place, making it easier to maintain and reuse across multiple tests.
First, we have the King class. This class represents a king with certain behaviors and states. The king can be drunk or sober, happy or unhappy. The king can also flirt with a queen, which may affect his happiness.
public class King implements Royalty {
boolean isDrunk = false;
boolean isHappy = false;
@Override
public void makeDrunk() {
isDrunk = true;
}
@Override
public void makeSober() {
isDrunk = false;
}
@Override
public void makeHappy() {
isHappy = true;
}
@Override
public void makeUnhappy() {
isHappy = false;
}
public boolean isHappy() {
return isHappy;
}
public void flirt(Queen queen) {
var flirtStatus = queen.getFlirted(this);
if (!flirtStatus) {
this.makeUnhappy();
} else {
this.makeHappy();
}
}
}
The RoyaltyObjectMother class is where the Object Mother pattern is implemented. This class provides static methods to create different types of King and Queen objects. These methods encapsulate the logic for creating these objects, making it easier to create them in a consistent way across multiple tests.
class RoyaltyObjectMother {
static King createDrunkKing() {
var king = new King();
king.makeDrunk();
return king;
}
static King createHappyKing() {
var king = new King();
king.makeHappy();
return king;
}
// Other methods to create different types of King and Queen objects...
}
In the RoyaltyObjectMotherTest class, we can see how the Object Mother pattern is used to create objects for testing. The RoyaltyObjectMother class is used to create King and Queen objects in different states, which are then used in the tests.
class RoyaltyObjectMotherTest {
@Test
void unsuccessfulKingFlirt() {
var soberUnhappyKing = RoyaltyObjectMother.createSoberUnhappyKing();
var flirtyQueen = RoyaltyObjectMother.createFlirtyQueen();
soberUnhappyKing.flirt(flirtyQueen);
assertFalse(soberUnhappyKing.isHappy());
}
// Other tests...
}
In this way, the Object Mother pattern simplifies the creation of objects for testing, making the tests easier to read and maintain.
Use the Object Mother pattern when
Benefits:
Trade-offs: