/*
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.jackson;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.math.BigInteger;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.node.NullNode;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.boot.jackson.NameAndAgeJsonComponent.Deserializer;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
/**
* Tests for {@link JsonObjectDeserializer}.
*
* @author Phillip Webb
*/
public class JsonObjectDeserializerTests {
@Rule
public ExpectedException thrown = ExpectedException.none();
private TestJsonObjectDeserializer<Object> testDeserializer = new TestJsonObjectDeserializer<>();
@Test
public void deserializeObjectShouldReadJson() throws Exception {
Deserializer deserializer = new NameAndAgeJsonComponent.Deserializer();
SimpleModule module = new SimpleModule();
module.addDeserializer(NameAndAge.class, deserializer);
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(module);
NameAndAge nameAndAge = mapper.readValue("{\"name\":\"spring\",\"age\":100}",
NameAndAge.class);
assertThat(nameAndAge.getName()).isEqualTo("spring");
assertThat(nameAndAge.getAge()).isEqualTo(100);
}
@Test
public void nullSafeValueWhenValueIsNullShouldReturnNull() throws Exception {
String value = this.testDeserializer.testNullSafeValue(null, String.class);
assertThat(value).isNull();
}
@Test
public void nullSafeValueWhenClassIsNullShouldThrowException() throws Exception {
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("Type must not be null");
this.testDeserializer.testNullSafeValue(mock(JsonNode.class), null);
}
@Test
public void nullSafeValueWhenClassIsStringShouldReturnString() throws Exception {
JsonNode node = mock(JsonNode.class);
given(node.textValue()).willReturn("abc");
String value = this.testDeserializer.testNullSafeValue(node, String.class);
assertThat(value).isEqualTo("abc");
}
@Test
public void nullSafeValueWhenClassIsBooleanShouldReturnBoolean() throws Exception {
JsonNode node = mock(JsonNode.class);
given(node.booleanValue()).willReturn(true);
Boolean value = this.testDeserializer.testNullSafeValue(node, Boolean.class);
assertThat(value).isTrue();
}
@Test
public void nullSafeValueWhenClassIsLongShouldReturnLong() throws Exception {
JsonNode node = mock(JsonNode.class);
given(node.longValue()).willReturn(10L);
Long value = this.testDeserializer.testNullSafeValue(node, Long.class);
assertThat(value).isEqualTo(10L);
}
@Test
public void nullSafeValueWhenClassIsIntegerShouldReturnInteger() throws Exception {
JsonNode node = mock(JsonNode.class);
given(node.intValue()).willReturn(10);
Integer value = this.testDeserializer.testNullSafeValue(node, Integer.class);
assertThat(value).isEqualTo(10);
}
@Test
public void nullSafeValueWhenClassIsShortShouldReturnShort() throws Exception {
JsonNode node = mock(JsonNode.class);
given(node.shortValue()).willReturn((short) 10);
Short value = this.testDeserializer.testNullSafeValue(node, Short.class);
assertThat(value).isEqualTo((short) 10);
}
@Test
public void nullSafeValueWhenClassIsDoubleShouldReturnDouble() throws Exception {
JsonNode node = mock(JsonNode.class);
given(node.doubleValue()).willReturn(1.1D);
Double value = this.testDeserializer.testNullSafeValue(node, Double.class);
assertThat(value).isEqualTo(1.1D);
}
@Test
public void nullSafeValueWhenClassIsFloatShouldReturnFloat() throws Exception {
JsonNode node = mock(JsonNode.class);
given(node.floatValue()).willReturn(1.1F);
Float value = this.testDeserializer.testNullSafeValue(node, Float.class);
assertThat(value).isEqualTo(1.1F);
}
@Test
public void nullSafeValueWhenClassIsBigDecimalShouldReturnBigDecimal()
throws Exception {
JsonNode node = mock(JsonNode.class);
given(node.decimalValue()).willReturn(BigDecimal.TEN);
BigDecimal value = this.testDeserializer.testNullSafeValue(node,
BigDecimal.class);
assertThat(value).isEqualTo(BigDecimal.TEN);
}
@Test
public void nullSafeValueWhenClassIsBigIntegerShouldReturnBigInteger()
throws Exception {
JsonNode node = mock(JsonNode.class);
given(node.bigIntegerValue()).willReturn(BigInteger.TEN);
BigInteger value = this.testDeserializer.testNullSafeValue(node,
BigInteger.class);
assertThat(value).isEqualTo(BigInteger.TEN);
}
@Test
public void nullSafeValueWhenClassIsUnknownShouldThrowException() throws Exception {
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("Unsupported value type java.io.InputStream");
this.testDeserializer.testNullSafeValue(mock(JsonNode.class), InputStream.class);
}
@Test
public void getRequiredNodeWhenTreeIsNullShouldThrowException() throws Exception {
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("Tree must not be null");
this.testDeserializer.testGetRequiredNode(null, "test");
}
@Test
public void getRequiredNodeWhenNodeIsNullShouldThrowException() throws Exception {
JsonNode tree = mock(JsonNode.class);
given(tree.get("test")).willReturn(null);
this.thrown.expect(IllegalStateException.class);
this.thrown.expectMessage("Missing JSON field 'test'");
this.testDeserializer.testGetRequiredNode(tree, "test");
}
@Test
public void getRequiredNodeWhenNodeIsNullNodeShouldThrowException() throws Exception {
JsonNode tree = mock(JsonNode.class);
given(tree.get("test")).willReturn(NullNode.instance);
this.thrown.expect(IllegalStateException.class);
this.thrown.expectMessage("Missing JSON field 'test'");
this.testDeserializer.testGetRequiredNode(tree, "test");
}
@Test
public void getRequiredNodeWhenNodeIsFoundShouldReturnNode() throws Exception {
JsonNode node = mock(JsonNode.class);
JsonNode tree = node;
given(tree.get("test")).willReturn(node);
assertThat(this.testDeserializer.testGetRequiredNode(tree, "test"))
.isEqualTo(node);
}
static class TestJsonObjectDeserializer<T> extends JsonObjectDeserializer<T> {
@Override
protected T deserializeObject(JsonParser jsonParser,
DeserializationContext context, ObjectCodec codec, JsonNode tree)
throws IOException {
return null;
}
public <D> D testNullSafeValue(JsonNode jsonNode, Class<D> type) {
return nullSafeValue(jsonNode, type);
}
public JsonNode testGetRequiredNode(JsonNode tree, String fieldName) {
return getRequiredNode(tree, fieldName);
}
}
}