If you've ever written unit tests in Java for a service layer, you probably know how quickly your test code can get cluttered with countless mock helper methods. Especially when you're mocking objects with several fields — it gets repetitive and hard to read.

Let me show you how switching to a Mock Builder Pattern can clean up your test suite and make your life a whole lot easier.

The Problem with Traditional Mocking
Here’s a simple UserValidator that validates a list of users:

public class UserValidator {
    public void validateUsers(List users) {
        usersShouldBeAdults(users);
        namesAndSurnamesShouldStartWithUpperCase(users);
        usersShouldBeFromEurope(users);
    }
    // ... methods omitted for brevity ...
}

Your User object might look like this:

@Getter
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
public class User {
    UUID id;
    String name;
    String surname;
    String country;
    int age;
}

When it’s time to test, you might reach for helper methods like:

private User getUserWithAge(int age) { ... }
private User getUserWithAgeAndName(String name, int age) { ... }
private User getUserWithAgeAndNameAndSurname(String name, String surname, int age) { ... }
private User getFullUser(String name, String surname, String country, int age) { ... }

That’s fine at first... but it quickly spirals into a mess of methods just to cover all combinations of fields. Not great.

✅ Enter the Mock Builder Pattern
Instead of creating dozens of helpers, let’s use a single, flexible mock builder using Lombok’s @Builder:

@Builder(builderMethodName = "user")
private static User getUserBuilder(
    String name,
    String surname,
    String country,
    Integer age
) {
    User user = mock(User.class);
    if (nonNull(name)) given(user.getName()).willReturn(name);
    if (nonNull(surname)) given(user.getSurname()).willReturn(surname);
    if (nonNull(country)) given(user.getCountry()).willReturn(country);
    if (nonNull(age)) given(user.getAge()).willReturn(age);
    return user;
}

Now, your tests become elegant and readable:

val users = List.of(
    user().name("Alice").surname("Smith").country("France").age(30).build(),
    user().name("Bob").surname("Brown").country("Germany").age(25).build()
);

You specify only the fields you need. No more boilerplate, no more bloated test classes.

Test Case Side-by-Side
Without Mock Builder

val users = List.of(
    getUserWithAgeAndNameAndSurname("Jason", "born", 30),
    getUserWithAge(21)
);

✅ With Mock Builder

val users = List.of(
    user().name("Jason").surname("born").age(30).build(),
    user().age(21).build()
);

🛠️ When to Use It

  • Your objects have optional or many fields
  • You're mocking with Mockito
  • You want cleaner, DRY test code
  • You hate writing getUserWithXAndY() for the 10th time

🔗 Code Sample
The full example is available here GitHub mock builder project.

Happy testing! 🧪