问题描述
假设有以下 POJO:
@input()
get disabled(): boolean {
return this.internaldisabled;
}
set disabled(value: boolean) {
console.log(value);
this.internaldisabled = coerceBooleanProperty(value);
if (this.internaldisabled) {
this.input.disable();
} else {
this.input.enable();
};
this.stateChanges.next();
}
现在我想为这个类生成各种测试数据。每当某些字段未明确设置时,应设置默认值。请记住,我无法将 Lombok 的 @Getter
@Setter
public class UserRequest {
private String username;
private String password;
private String email;
}
或 @Builder
添加到原始类或以其他方式对其进行修改。
所以我想出了以下帮助类:
@Builder.Default
虽然这对于只有一些字段的类来说是可以的,但如果有更多的字段和测试数据的某些变体,它就会变得乏味。
我的第一个想法是在 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,email);
}
public static UserRequest createuserRequestWithUsernameAndPassword(String username,String password) {
return createuserRequest(username,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;
}
}
的方法级别使用 Lombok 的 @Builder
:
createuserRequest()
允许以下内容:
@Builder
public static UserRequest createuserRequest(String username,String email) {
final UserRequest userRequest = new UserRequest();
userRequest.setUsername(username);
userRequest.setPassword(password);
userRequest.setEmail(email);
return userRequest;
}
但是,这不会为(在本例中为 UserRequestTestDataBuilder.builder()
.username("foo")
.password("bar")
.build();
)设置任何默认值。是否有某种模式可以简化这种方法?
解决方法
为什么不只是...
@Getter
@Setter
public class UserRequest {
private String username = "";
private String password = "";
private String email = "(unknown email)";
}
如果有人运行 new UserRequest()
,那将起作用,并且 UR 将具有默认值。 .set
可用于更改任何或所有这些字段的值。
免责声明:我是 lombok 的核心贡献者之一。
-- 编辑 --
啊哈,你不能改变原来的。如果允许将 null
计为哨兵(例如,作为需要默认值的信号):
@Builder
public static UserRequest newUserRequest(String username,String password,String email) {
UserRequest ur = new UserRequest();
ur.setUsername(username == null ? DEFAULT_USERNAME : username);
// etc
return ur;
}
如果您希望 UR 设置为某些默认值,但如果有人明确执行 buildUserRequest().username(null).build()
,那么 username
应该是 null
,oof。如果您无法更改 UserRequest 的来源,我不确定是否有更简单的方法。
您实际上可以通过在您的 util 类中的一些解决方法来实现这一点,同时使用 @Builder
注释的方法添加以下与 lombok 生成的构建器类同名的类。
public class UserRequestTestDataUtils {
// leave this method as such,without any null checks.
@Builder
public static UserRequest newUserRequest(String username,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 仍会像往常一样在构建器类中生成其他必需的方法。您可以像这样覆盖 lombok 生成的构建器类中的任何方法/字段的行为。 (不确定这样做是否正确,但确实有效!)
注意:在构建对象时传递显式 null
会将值设置为 null
//this would generate password and email with the given default values.
UserRequestTestDataUtils.builder().username("testname").build();