使用辅助方法为 Java 个对象生成测试数据时提供默认值
Provide default values when generating test data for Java objects with helper methods
假设以下 POJO:
@Getter
@Setter
public class UserRequest {
private String username;
private String password;
private String email;
}
现在我想为此class生成各种测试数据。每当某些字段未明确设置时,应设置默认值。请记住,我不能在原来的class上加上Lombok的@Builder
或@Builder.Default
,也不能用其他方式修改。
所以我想出了下面的帮手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;
}
}
虽然这对于只有一些字段的 classes 是可以的,但是如果有更多的字段并且对于测试数据的某些变化,它会变得乏味。
我的第一个想法是在 createUserRequest()
的方法级别上使用 Lombok 的 @Builder
:
@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;
}
这将允许以下内容:
UserRequestTestDataBuilder.builder()
.username("foo")
.password("bar")
.build();
但是,这不会为(在本例中 email
)设置任何默认值。是否有一些模式可以简化这种方法?
为什么不...
@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 class 中使用一些变通方法来实现此目的,以及使用 @Builder
注释的方法添加以下 class 与构建器同名 class 将由 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 仍会像往常一样在构建器中生成其他所需的方法 class。您可以像这样覆盖 lombok 生成的构建器 class 中任何 methods/fields 的行为。 (不确定这样做是否正确,但确实有效!)
注意: 在构建对象时传递显式 null
会将值设置为 null
//this would generate password and email with the given default values.
UserRequestTestDataUtils.builder().username("testname").build();
假设以下 POJO:
@Getter
@Setter
public class UserRequest {
private String username;
private String password;
private String email;
}
现在我想为此class生成各种测试数据。每当某些字段未明确设置时,应设置默认值。请记住,我不能在原来的class上加上Lombok的@Builder
或@Builder.Default
,也不能用其他方式修改。
所以我想出了下面的帮手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;
}
}
虽然这对于只有一些字段的 classes 是可以的,但是如果有更多的字段并且对于测试数据的某些变化,它会变得乏味。
我的第一个想法是在 createUserRequest()
的方法级别上使用 Lombok 的 @Builder
:
@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;
}
这将允许以下内容:
UserRequestTestDataBuilder.builder()
.username("foo")
.password("bar")
.build();
但是,这不会为(在本例中 email
)设置任何默认值。是否有一些模式可以简化这种方法?
为什么不...
@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 class 中使用一些变通方法来实现此目的,以及使用 @Builder
注释的方法添加以下 class 与构建器同名 class 将由 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 仍会像往常一样在构建器中生成其他所需的方法 class。您可以像这样覆盖 lombok 生成的构建器 class 中任何 methods/fields 的行为。 (不确定这样做是否正确,但确实有效!)
注意: 在构建对象时传递显式 null
会将值设置为 null
//this would generate password and email with the given default values.
UserRequestTestDataUtils.builder().username("testname").build();