2016-11-27 3 views
0

У меня есть базовый тест ресурсов, который использует ResourceTestRule для запуска моего ресурса и Джерси в качестве клиента, чтобы сделать запрос - большая часть этого была взята непосредственно из документов. Проблема в том, что я хочу: 1) проверить объект User на create и 2) НЕ сериализовать соль и пароль при переходе из объекта -> JSON в качестве учетной записи, чтобы они никогда не отображались в ответах.Тест ресурса Dropwizard, Джексон не заполняет поле, десериализует и сериализует?

Тест не работает и возвращает 422 без содержимого. Сообщение об ошибке проверки Hibernate никогда не пробивает, поэтому единственное, что я вижу, это отказ от утверждения Response.Status.OK. У меня есть ограничение валидации на password, которое равно @NotEmpty - комментируя это, проходит тест. Я также @JsonIgnore с использованием пароля, поскольку он был удобным и сделал это так, чтобы он никогда не подвергался воздействию ответа JSON, но я открыт для этого другим способом. Лучше всего предположить, что где-то во внутренних подразделениях Hibernate/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("[email protected]"); 
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; 
    } 

ответ

0

Я вижу путь вокруг этого. Вместо:

Entity.entity(user, MediaType.APPLICATION_JSON_TYPE) 

Вы можете попробовать использовать json пользователя (созданный вручную). Но, конечно, если вы используете тот же код для производства (а не только для тестов), то он не будет работать.

+0

Да, я считал это. Я бы, вероятно, сделал это, если бы не было другого способа, но было бы позором не использовать встроенные инструменты для тестирования. – Justin

Смежные вопросы