Assume the following POJO:
@Getter
@Setter
public class UserRequest {
private String username;
private String password;
private String email;
}
Now I'd like to generate various test data for this class. Whenever some field is not set explicitly, a default value shall be set. Please bear in mind that I cannot add Lombok's @Builder
or @Builder.Default
to the original class or modify it in other ways.
So I came up with the following helper class:
public class UserRequestTestDataUtils {
public static final String DEFAULT_USERNAME = "foo";
public static final String DEFAULT_PASSWORD = "bar";
public static final String DEFAULT_EMAIL = "foo@bar.com";
public static UserRequest createUserRequestWithUsername(String username) {
return createUserRequest(username, DEFAULT_PASSWORD, DEFAULT_EMAIL);
}
public static UserRequest createUserRequestWithPassword(String password) {
return createUserRequest(DEFAULT_USERNAME, password, DEFAULT_EMAIL);
}
public static UserRequest createUserRequestWithEmail(String email) {
return createUserRequest(DEFAULT_USERNAME, DEFAULT_PASSWORD, email);
}
public static UserRequest createUserRequestWithUsernameAndPassword(String username, String password) {
return createUserRequest(username, password, DEFAULT_EMAIL);
}
public static UserRequest createUserRequest(String username, String password, String email) {
final UserRequest userRequest = new UserRequest();
userRequest.setUsername(username);
userRequest.setPassword(password);
userRequest.setEmail(email);
return userRequest;
}
}
While this is ok for classes with only some fields, it gets tedious if there are more fields and for certain variations of the test data.
My first idea was to use Lombok's @Builder
on the method level for createUserRequest()
:
@Builder
public static UserRequest createUserRequest(String username, String password, String email) {
final UserRequest userRequest = new UserRequest();
userRequest.setUsername(username);
userRequest.setPassword(password);
userRequest.setEmail(email);
return userRequest;
}
Which would allow the following:
UserRequestTestDataBuilder.builder()
.username("foo")
.password("bar")
.build();
However, this doesn't set any default value for (in this case email
). Is there some pattern which could simplify this approach?
You could actually achieve this with a little workaround in your util class, along with the method annotated with @Builder
add the below class with the same name as the builder class that would be generated by lombok.
public class UserRequestTestDataUtils {
// leave this method as such, without any null checks.
@Builder
public static UserRequest newUserRequest(String username, String password, String email) {
UserRequest ur = new UserRequest();
ur.setUsername(username);
// etc
return ur;
}
// Provide the default values here.
public static class UserRequestBuilder {
private String username = "foo";
private String password = "bar";
private String email = "foo@bar.com";
}
}
Lombok would still generate the other required methods in the builder class as usual. You could override the behavior of any methods/fields within the lombok generated builder class like this. (Not sure if this is a right thing to do, but it works!)
NOTE : Passing an explicit null
while building the object would set the value as null
//this would generate password and email with the given default values.
UserRequestTestDataUtils.builder().username("testname").build();