Simplify Your Unit Tests with Mock Builders in Java

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() );

Apr 18, 2025 - 08:19
 0
Simplify Your Unit Tests with Mock Builders in Java

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()
);