Let's suppose there is the following exemplary class which is not under my control, ie I cannot change its behavior.
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class RegistrationRequest {
private String email;
private String emailRepeat;
private String password;
private String passwordRepeat;
}
I'd like to use Lombok @Builder
to build test data for this class, so I put the @Builder
annotation on the method level like this:
public class SomeTestUtils {
public static final String DEFAULT_EMAIL = "foo@bar.com";
public static final String DEFAULT_EMAIL_REPEAT = "foo@bar.com";
public static final String DEFAULT_PASSWORD = "my-password";
public static final String DEFAULT_PASSWORD_REPEAT = "my-password";
@Builder(builderMethodName = "aRegistrationRequest", setterPrefix = "with")
public static RegistrationRequest buildRegistrationRequest(String email, String emailRepeat, String password, String passwordRepeat) {
final RegistrationRequest request = new RegistrationRequest();
request.setEmail(email);
request.setEmailRepeat(emailRepeat);
request.setPasswort(password);
return request;
}
}
This allows me to create an object like this:
SomeTestUtils.aRegistrationRequest()
.withEmail("foo@bar.com")
.withEmailRepeat("foo@bar.com")
.withPassword("my-password")
.withPasswordRepeat("my-password")
.build();
But now I'd like to provide default value for any field which is not explicitly set. So if I did this, then an object with all the defaults shall be created:
SomeTestUtils.aRegistrationRequest().build();
Lombok developer here:
You can't, not directly. The code needs to be syntactically valid java before lombok gets to do its thing, and there isn't a feasible way (at least, we've never managed to think of something acceptable) to write what you want in java syntax. These things all simply won't work:
/* 1 */ void foo(int param = 5) {}
/* 2 */ void foo(@DefaultValue(5) int param) {}
/* 3 */ void foo(@DefaultValue("5") int param) {}
/* 4 */ void foo(int param) {
defaultValues: {
param = 5;
}
}
@IntDefaultValue
, @StringDefaultValue
, etc, but [A] that just lets you cover primitives, strings, Class<?>
values, enums, and arrays of those types - and nothing else, and [B] that means you can only supply compile time constants. This is far too restrictive.final
to every parameter (if you're one of those, I suggest you cut that out. If you hate mutating params, add a linting or IDE rule to prevent it, and remove that clutter from your code, please). It's also easy to typo the defaultValues:
param and you get zero auto-complete help. If null
is not a sensible value for the stuff you want to provide defaults for, treat null
as "I wanted the default". Something like:
@Builder void foo(Integer x) {
if (x == null) x = 5;
// carry on with the code as normal
}
or if you prefer never mutating your params (again I implore you - sanity checks and defaulting behaviour SHOULD be applied to the parameter; failure to do so means it is way too easy to accidentally use the 'wrong' one), you can do this:
@Builder void foo(Integer paramIn) {
int param == paramIn == null ? 5 : paramIn;
// carry on as normal. Woe is you if you use paramIn.
}
I suggest you add some javadoc that explains this, of course.
If null
is a sensible option, but should not be the default, we're mostly in 'wow, that is so rare and exotic, it is no longer boilerplate' territory.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.