【发布时间】:2016-11-27 14:39:47
【问题描述】:
我有一个基本资源测试,它使用 ResourceTestRule 运行我的资源,并使用 Jersey 作为客户端来发出请求 - 其中大部分是直接从文档中获取的。问题是我想 1) 在 create 上验证 User 对象,以及 2) 在从 Object -> JSON 开始时不序列化 salt 和密码,作为一个包罗万象,因此这些永远不会在响应中公开。
测试失败并返回没有内容的 422。 Hibernate 验证错误消息永远不会通过,所以我最终看到的唯一一件事是 Response.Status.OK 断言的失败。我对password 有一个验证约束,即@NotEmpty - 将其注释掉会使测试通过。我也是@JsonIgnoreing 密码获取器,因为它很方便并且使它永远不会暴露在 JSON 响应中,但我愿意以不同的方式这样做。我最好的猜测是,在 Hibernate/Jersey 内部的某个地方,我传递给 Jersey 请求的实体(Entity.entity(user, MediaType.APPLICATION_JSON_TYPE))再次被反序列化和序列化,并且由于无法获取密码而丢失了。
这里是测试规则:
@ClassRule public static final ResourceTestRule
userResource =
ResourceTestRule.builder().addResource(new UserResource(USER_DAO, PERSON_DAO)).build();
在assertThat(response.getStatusInfo()).isEqualTo(Response.Status.OK); 失败的测试体:
when(USER_DAO.save(any(User.class))).thenReturn(Optional.of(user));
when(PERSON_DAO.save(any(Person.class))).thenReturn(Optional.of(person));
final Response
response =
userResource.client().target("/user").request(MediaType.APPLICATION_JSON_TYPE)
.post(Entity.entity(user, MediaType.APPLICATION_JSON_TYPE));
assertThat(response.getStatusInfo()).isEqualTo(Response.Status.OK);
verify(USER_DAO).save(userCaptor.capture());
verify(PERSON_DAO).save(personCaptor.capture());
User savedUser = userCaptor.getValue();
assertThat(savedUser).isEqualToIgnoringGivenFields(user, "salt", "password", "person");
assertThat(savedUser.getPerson()).isEqualToComparingFieldByFieldRecursively(user.getPerson());
这是实际的资源方法:
@POST
@Timed
public User create(@NotNull @Valid User user) {
if (user.getPerson() != null) {
try {
personDAO.save(user.getPerson());
// todo justin - abstract this
} catch (DuplicateKeyException e) {
throw new WebApplicationException("That person exists already.", Response.SC_BAD_REQUEST);
}
}
try {
user = userDAO.save(user).get();
} catch (DuplicateKeyException e) {
throw new WebApplicationException("That user exists already.", Response.SC_BAD_REQUEST);
}
return user;
}
这是预期的用户(我从模拟返回的用户UserDAO):
user = new User();
user.setEmail("justin@email.com");
user.setPassword("test");
person = new Person();
person.setFirstName("Justin");
person.setLastName("K");
user.setPerson(person);
以及User 类的相关部分:
public class User extends BaseModel implements Principal {
@Id
@JsonSerialize(using = ToStringSerializer.class)
private ObjectId id = new ObjectId();
@Email
@NotBlank
private String email;
@NotEmpty
private byte[] password;
private byte[] salt = Security.getSalt();
public ObjectId getId() {
return id;
}
public void setId(ObjectId id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@JsonIgnore // ignored when serialized FROM object TO json
public byte[] getPassword() {
return password;
}
@JsonProperty
public void setPassword(byte[] password) {
this.password = password;
}
@JsonProperty
public void setPassword(String password) {
this.password = Security.hashPassword(password.toCharArray(), this.getSalt());
}
@JsonIgnore // ignored when serialized FROM object TO json
public byte[] getSalt() {
return salt;
}
@JsonProperty
public void setSalt(byte[] salt) {
this.salt = salt;
}
【问题讨论】:
标签: hibernate unit-testing jersey jackson dropwizard