MergeWithCreator1921Test.java
package com.fasterxml.jackson.databind.tofix;
import java.util.Objects;
import org.junit.jupiter.api.Test;
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.exc.ValueInstantiationException;
import com.fasterxml.jackson.databind.testutil.DatabindTestUtil;
import com.fasterxml.jackson.databind.testutil.failure.JacksonTestFailureExpected;
import static org.junit.jupiter.api.Assertions.fail;
// For [databind#1921]: Creator method not used when merging even if there is
// no feasible alternative. Unclear whether this can even theoretically be
// improved since combination of Creator + Setter(s)/field is legit; but use
// of Creator always means that operation is not true merge.
// But added test just in case future brings us a good idea of way forward.
class MergeWithCreator1921Test extends DatabindTestUtil {
static class Account {
@JsonMerge(value = OptBoolean.TRUE)
private final Validity validity;
@JsonCreator
public Account(@JsonProperty(value = "validity", required = true) Validity validity) {
this.validity = validity;
}
public Validity getValidity() {
return validity;
}
}
static class Validity {
public static final String VALID_FROM_CANT_BE_NULL = "Valid from can't be null";
public static final String VALID_TO_CANT_BE_BEFORE_VALID_FROM = "Valid to can't be before valid from";
private final String _validFrom;
private final String _validTo;
@JsonCreator
public Validity(@JsonProperty(value = "validFrom", required = true) String validFrom,
@JsonProperty("validTo") String validTo) {
checkValidity(validFrom, validTo);
this._validFrom = validFrom;
this._validTo = validTo;
}
private void checkValidity(String from, String to) {
Objects.requireNonNull(from, VALID_FROM_CANT_BE_NULL);
if (to != null) {
if (from.compareTo(to) > 0) {
throw new IllegalStateException(VALID_TO_CANT_BE_BEFORE_VALID_FROM);
}
}
}
public String getValidFrom() {
return _validFrom;
}
public String getValidTo() {
return _validTo;
}
}
@JacksonTestFailureExpected
@Test
void mergeWithCreator() throws Exception {
final String JSON = "{ \"validity\": { \"validFrom\": \"2018-02-01\", \"validTo\": \"2018-01-31\" } }";
final ObjectMapper mapper = newJsonMapper();
try {
mapper.readValue(JSON, Account.class);
fail("Should not pass");
} catch (ValueInstantiationException e) {
verifyException(e, "Cannot construct");
verifyException(e, Validity.VALID_TO_CANT_BE_BEFORE_VALID_FROM);
}
try {
Account acc = new Account(new Validity("abc", "def"));
mapper.readerForUpdating(acc)
.readValue(JSON);
fail("Should not pass");
} catch (ValueInstantiationException e) {
verifyException(e, "Cannot construct");
verifyException(e, Validity.VALID_TO_CANT_BE_BEFORE_VALID_FROM);
}
}
}