Commit 24ab2bd8 authored by Phillip Webb's avatar Phillip Webb

Add utilities to help with JSON testing

Add Jackson, Gson and Basic String helper classes that allow AssertJ
assertions to be used to test JSON.

Fixes gh-5471
parent 45c4f5f3
......@@ -25,6 +25,16 @@
<artifactId>spring-boot</artifactId>
</dependency>
<!-- Optional -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
......@@ -60,6 +70,11 @@
<artifactId>mockito-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.skyscreamer</groupId>
<artifactId>jsonassert</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
......@@ -102,6 +117,10 @@
<optional>true</optional>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
......
/*
* Copyright 2012-2016 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.test.json;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
/**
* AssertJ based JSON tester that works with basic JSON strings. Allows testing of JSON
* payloads created from some any source, for example:<pre class="code">
* public class ExampleObjectJsonTests {
*
* private BasicJsonTester = new BasicJsonTester(getClass());
*
* &#064;Test
* public void testWriteJson() {
* assertThat(json.from("example.json")).extractingJsonPathStringValue("@.name")
.isEqualTo("Spring");
* }
*
* }
* </pre>
*
* See {@link AbstractJsonMarshalTester} for more details.
*
* @author Phillip Webb
* @since 1.4.0
*/
public class BasicJsonTester {
private final JsonLoader loader;
/**
* Create a new {@link BasicJsonTester} instance.
* @param resourceLoadClass the source class used to load resources
*/
public BasicJsonTester(Class<?> resourceLoadClass) {
Assert.notNull(resourceLoadClass, "ResourceLoadClass must not be null");
this.loader = new JsonLoader(resourceLoadClass);
}
/**
* Create JSON content from the specified String source. The source can contain the
* JSON itself or, if it ends with {@code .json}, the name of a resource to be loaded
* using {@code resourceLoadClass}.
* @param source JSON content or a {@code .json} resource name
* @return the JSON content
* @throws IOException on load error
*/
public JsonContent<Object> from(CharSequence source) throws IOException {
return getJsonContent(this.loader.getJson(source));
}
/**
* Create JSON content from the specified resource path.
* @param path the path of the resource to load
* @param resourceLoadClass the classloader used load the resource
* @return the JSON content
* @throws IOException on load error
*/
public JsonContent<Object> from(String path, Class<?> resourceLoadClass)
throws IOException {
return getJsonContent(this.loader.getJson(path, resourceLoadClass));
}
/**
* Create JSON content from the specified JSON bytes.
* @param source the bytes of JSON
* @return the JSON content
* @throws IOException on load error
*/
public JsonContent<Object> from(byte[] source) throws IOException {
return getJsonContent(this.loader.getJson(source));
}
/**
* Create JSON content from the specified JSON file.
* @param source the file containing JSON
* @return the JSON content
* @throws IOException on load error
*/
public JsonContent<Object> from(File source) throws IOException {
return getJsonContent(this.loader.getJson(source));
}
/**
* Create JSON content from the specified JSON input stream.
* @param source the input stream containing JSON
* @return the JSON content
* @throws IOException on load error
*/
public JsonContent<Object> from(InputStream source) throws IOException {
return getJsonContent(this.loader.getJson(source));
}
/**
* Create JSON content from the specified JSON resource.
* @param source the resource containing JSON
* @return the JSON content
* @throws IOException on load error
*/
public JsonContent<Object> from(Resource source) throws IOException {
return getJsonContent(this.loader.getJson(source));
}
private JsonContent<Object> getJsonContent(String json) {
return new JsonContent<Object>(this.loader.getResourceLoadClass(), null, json);
}
}
/*
* Copyright 2012-2016 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.test.json;
import java.io.IOException;
import java.io.Reader;
import com.google.gson.Gson;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.core.ResolvableType;
import org.springframework.util.Assert;
/**
* AssertJ based JSON tester backed by Gson. Usually instantiated via
* {@link #initFields(Object, Gson)}, for example: <pre class="code">
* public class ExampleObjectJsonTests {
*
* private GsonTester&lt;ExampleObject&gt; json;
*
* &#064;Before
* public void setup() {
* Gson gson = new GsonBuilder().create();
* GsonTester.initFields(this, gson);
* }
*
* &#064;Test
* public void testWriteJson() {
* ExampleObject object = //...
* assertThat(json.write(object)).isEqualToJson("expected.json");
* }
*
* }
* </pre>
*
* See {@link AbstractJsonMarshalTester} for more details.
*
* @param <T> The type under test
* @author Phillip Webb
* @since 1.4.0
*/
public class GsonTester<T> extends AbstractJsonMarshalTester<T> {
private final Gson gson;
/**
* Create a new {@link GsonTester} instance.
* @param resourceLoadClass the source class used to load resources
* @param type the type under test
* @param gson the Gson instance
* @see #initFields(Object, Gson)
*/
public GsonTester(Class<?> resourceLoadClass, ResolvableType type, Gson gson) {
super(resourceLoadClass, type);
Assert.notNull(gson, "Gson must not be null");
this.gson = gson;
}
@Override
protected String writeObject(T value, ResolvableType type) throws IOException {
return this.gson.toJson(value, type.getType());
}
@Override
protected T readObject(Reader reader, ResolvableType type) throws IOException {
return this.gson.fromJson(reader, type.getType());
}
/**
* Utility method to initialize {@link JacksonTester} fields. See {@link JacksonTester
* class-level documentation} for example usage.
* @param testInstance the test instance
* @param gson the Gson instance
*/
public static void initFields(Object testInstance, Gson gson) {
new GsonFieldInitializer().initFields(testInstance, gson);
}
/**
* Utility method to initialize {@link JacksonTester} fields. See {@link JacksonTester
* class-level documentation} for example usage.
* @param testInstance the test instance
* @param gson an object factory to create the Gson instance
*/
public static void initFields(Object testInstance, ObjectFactory<Gson> gson) {
new GsonFieldInitializer().initFields(testInstance, gson);
}
/**
* {@link JsonTesterFieldInitializer} for Gson.
*/
private static class GsonFieldInitializer extends FieldInitializer<Gson> {
protected GsonFieldInitializer() {
super(GsonTester.class);
}
@Override
protected AbstractJsonMarshalTester<Object> createTester(
Class<?> resourceLoadClass, ResolvableType type, Gson marshaller) {
return new GsonTester<Object>(resourceLoadClass, type, marshaller);
}
}
}
/*
* Copyright 2012-2016 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.test.json;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.core.ResolvableType;
import org.springframework.util.Assert;
/**
* AssertJ based JSON tester backed by Jackson. Usually instantiated via
* {@link #initFields(Object, ObjectMapper)}, for example: <pre class="code">
* public class ExampleObjectJsonTests {
*
* private JacksonTester&lt;ExampleObject&gt; json;
*
* &#064;Before
* public void setup() {
* ObjectMapper objectMapper = new ObjectMapper();
* JacksonTester.initFields(this, objectMapper);
* }
*
* &#064;Test
* public void testWriteJson() {
* ExampleObject object = //...
* assertThat(json.write(object)).isEqualToJson("expected.json");
* }
*
* }
* </pre>
*
* See {@link AbstractJsonMarshalTester} for more details.
*
* @param <T> The type under test
* @author Phillip Webb
* @since 1.4.0
*/
public class JacksonTester<T> extends AbstractJsonMarshalTester<T> {
private final ObjectMapper objectMapper;
/**
* Create a new {@link JacksonTester} instance.
* @param resourceLoadClass the source class used to load resources
* @param type the type under test
* @param objectMapper the Jackson object mapper
*/
public JacksonTester(Class<?> resourceLoadClass, ResolvableType type,
ObjectMapper objectMapper) {
super(resourceLoadClass, type);
Assert.notNull(objectMapper, "ObjectMapper must not be null");
this.objectMapper = objectMapper;
}
@Override
protected T readObject(InputStream inputStream, ResolvableType type)
throws IOException {
return this.objectMapper.readValue(inputStream, getType(type));
}
@Override
protected T readObject(Reader reader, ResolvableType type) throws IOException {
return this.objectMapper.readerFor(getType(type)).readValue(reader);
}
@Override
protected String writeObject(T value, ResolvableType type) throws IOException {
return this.objectMapper.writerFor(getType(type)).writeValueAsString(value);
}
private JavaType getType(ResolvableType type) {
return this.objectMapper.constructType(type.getType());
}
/**
* Utility method to initialize {@link JacksonTester} fields. See {@link JacksonTester
* class-level documentation} for example usage.
* @param testInstance the test instance
* @param objectMapper the object mapper
* @see #initFields(Object, ObjectMapper)
*/
public static void initFields(Object testInstance, ObjectMapper objectMapper) {
new JacksonFieldInitializer().initFields(testInstance, objectMapper);
}
/**
* Utility method to initialize {@link JacksonTester} fields. See {@link JacksonTester
* class-level documentation} for example usage.
* @param testInstance the test instance
* @param objectMapperFactory a factory to create the object mapper
* @see #initFields(Object, ObjectMapper)
*/
public static void initFields(Object testInstance,
ObjectFactory<ObjectMapper> objectMapperFactory) {
new JacksonFieldInitializer().initFields(testInstance, objectMapperFactory);
}
/**
* {@link JsonTesterFieldInitializer} for Jackson.
*/
private static class JacksonFieldInitializer extends FieldInitializer<ObjectMapper> {
protected JacksonFieldInitializer() {
super(JacksonTester.class);
}
@Override
protected AbstractJsonMarshalTester<Object> createTester(
Class<?> resourceLoadClass, ResolvableType type,
ObjectMapper marshaller) {
return new JacksonTester<Object>(resourceLoadClass, type, marshaller);
}
}
}
/*
* Copyright 2012-2016 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.test.json;
import org.assertj.core.api.AssertProvider;
import org.springframework.core.ResolvableType;
import org.springframework.util.Assert;
/**
* JSON content created usually from a JSON tester. Generally used only to
* {@link AssertProvider provide} {@link JsonContentAssert} to AssertJ {@code assertThat}
* calls.
*
* @param <T> The source type that created the content
* @author Phillip Webb
* @since 1.4.0
*/
public final class JsonContent<T> implements AssertProvider<JsonContentAssert> {
private final Class<?> resourceLoadClass;
private final ResolvableType type;
private final String json;
/**
* Create a new {@link JsonContent} instance.
* @param resourceLoadClass the source class used to load resources
* @param type the type under test (or {@code null} if not known)
* @param json the actual JSON content
*/
public JsonContent(Class<?> resourceLoadClass, ResolvableType type, String json) {
Assert.notNull(resourceLoadClass, "ResourceLoadClass must not be null");
Assert.notNull(json, "JSON must not be null");
this.resourceLoadClass = resourceLoadClass;
this.type = type;
this.json = json;
}
@Override
public JsonContentAssert assertThat() {
return new JsonContentAssert(this.resourceLoadClass, this.json);
}
/**
* Return the actual JSON content string.
* @return the JSON content
*/
public String getJson() {
return this.json;
}
@Override
public String toString() {
return "JsonContent " + this.json
+ (this.type == null ? "" : " created from " + this.type);
}
}
/*
* Copyright 2012-2016 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.test.json;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.util.FileCopyUtils;
/**
* Internal helper used to load JSON from various sources.
*
* @author Phillip Webb
*/
class JsonLoader {
private final Class<?> resourceLoadClass;
JsonLoader(Class<?> resourceLoadClass) {
this.resourceLoadClass = resourceLoadClass;
}
public Class<?> getResourceLoadClass() {
return this.resourceLoadClass;
}
public String getJson(CharSequence source) throws IOException {
if (source == null) {
return null;
}
if (source.toString().endsWith(".json")) {
return getJson(
new ClassPathResource(source.toString(), this.resourceLoadClass));
}
return source.toString();
}
public String getJson(String path, Class<?> resourceLoadClass) throws IOException {
return getJson(new ClassPathResource(path, resourceLoadClass));
}
public String getJson(byte[] source) throws IOException {
return getJson(new ByteArrayInputStream(source));
}
public String getJson(File source) throws IOException {
return getJson(new FileInputStream(source));
}
public String getJson(Resource source) throws IOException {
return getJson(source.getInputStream());
}
public String getJson(InputStream source) throws IOException {
return FileCopyUtils.copyToString(new InputStreamReader(source));
}
}
/*
* Copyright 2012-2016 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.test.json;
import org.assertj.core.api.AssertProvider;
import org.springframework.core.ResolvableType;
import org.springframework.util.Assert;
/**
* Object content usually created from {@link AbstractJsonMarshalTester}.Generally used
* only to {@link AssertProvider provide} {@link ObjectContentAssert} to AssertJ
* {@code assertThat} calls.
*
* @param <T> The content type
* @author Phillip Webb
* @since 1.4.0
*/
public final class ObjectContent<T> implements AssertProvider<ObjectContentAssert<T>> {
private final ResolvableType type;
private final T object;
/**
* Create a new {@link ObjectContent} instance.
* @param type the type under test (or {@code null} if not known)
* @param object the actual object content
*/
public ObjectContent(ResolvableType type, T object) {
Assert.notNull(object, "Object must not be null");
this.type = type;
this.object = object;
}
@Override
public ObjectContentAssert<T> assertThat() {
return new ObjectContentAssert<T>(this.object);
}
/**
* Return the actual object content.
* @return the object content
*/
public T getObject() {
return this.object;
}
@Override
public String toString() {
return "ObjectContent " + this.object
+ (this.type == null ? "" : " created from " + this.type);
}
}
/*
* Copyright 2012-2016 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.test.json;
import java.util.Map;
import org.assertj.core.api.AbstractMapAssert;
import org.assertj.core.api.AbstractObjectArrayAssert;
import org.assertj.core.api.AbstractObjectAssert;
import org.assertj.core.api.Assert;
import org.assertj.core.api.Assertions;
import org.assertj.core.internal.Objects;
/**
* AssertJ {@link Assert} for {@link JsonContent}.
*
* @param <A> The actual type
* @author Phillip Webb
* @since 1.4.0
*/
public class ObjectContentAssert<A>
extends AbstractObjectAssert<ObjectContentAssert<A>, A> {
protected ObjectContentAssert(A actual) {
super(actual, ObjectContentAssert.class);
}
/**
* Verifies that the actual value is an array, and returns an array assertion, to
* allow chaining of array-specific assertions from this call.
* @return a list assertion object
*/
public AbstractObjectArrayAssert<?, Object> asArray() {
Objects.instance().assertIsInstanceOf(this.info, this.actual, Object[].class);
return Assertions.assertThat((Object[]) this.actual);
}
/**
* Verifies that the actual value is a map, and returns a map assertion, to allow
* chaining of list-specific assertions from this call.
* @return a list assertion object
*/
@SuppressWarnings("unchecked")
public AbstractMapAssert<?, ?, Object, Object> asMap() {
Objects.instance().assertIsInstanceOf(this.info, this.actual, Map.class);
return Assertions.assertThat((Map<Object, Object>) this.actual);
}
}
/*
* Copyright 2012-2016 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.
*/
/**
* Support for testing JSON.
*/
package org.springframework.boot.test.json;
/*
* Copyright 2012-2016 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.test.json;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.springframework.core.ResolvableType;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.ReflectionUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link AbstractJsonMarshalTester}.
*
* @author Phillip Webb
*/
public abstract class AbstractJsonMarshalTesterTests {
private static final String JSON = "{\"name\":\"Spring\",\"age\":123}";
private static final String MAP_JSON = "{\"a\":" + JSON + "}";
private static final String ARRAY_JSON = "[" + JSON + "]";
private static final ExampleObject OBJECT = createExampleObject("Spring", 123);
private static final ResolvableType TYPE = ResolvableType
.forClass(ExampleObject.class);
@Rule
public ExpectedException thrown = ExpectedException.none();
@Rule
public TemporaryFolder temp = new TemporaryFolder();
@Test
public void writeShouldReturnJsonContent() throws Exception {
JsonContent<Object> content = createTester(TYPE).write(OBJECT);
assertThat(content).isEqualToJson(JSON);
}
@Test
public void writeListShouldReturnJsonContent() throws Exception {
ResolvableType type = ResolvableTypes.get("listOfExampleObject");
List<ExampleObject> value = Collections.singletonList(OBJECT);
JsonContent<Object> content = createTester(type).write(value);
assertThat(content).isEqualToJson(ARRAY_JSON);
}
@Test
public void writeArrayShouldReturnJsonContent() throws Exception {
ResolvableType type = ResolvableTypes.get("arrayOfExampleObject");
ExampleObject[] value = new ExampleObject[] { OBJECT };
JsonContent<Object> content = createTester(type).write(value);
assertThat(content).isEqualToJson(ARRAY_JSON);
}
@Test
public void writeMapShouldReturnJsonContent() throws Exception {
ResolvableType type = ResolvableTypes.get("mapOfExampleObject");
Map<String, Object> value = new LinkedHashMap<String, Object>();
value.put("a", OBJECT);
JsonContent<Object> content = createTester(type).write(value);
assertThat(content).isEqualToJson(MAP_JSON);
}
@Test
public void createWhenResourceLoadClassIsNullShouldThrowException() throws Exception {
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("ResourceLoadClass must not be null");
createTester(null, ResolvableType.forClass(ExampleObject.class));
}
@Test
public void createWhenTypeIsNullShouldThrowException() throws Exception {
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("Type must not be null");
createTester(getClass(), null);
}
@Test
public void parseBytesShouldReturnObject() throws Exception {
AbstractJsonMarshalTester<Object> tester = createTester(TYPE);
assertThat(tester.parse(JSON.getBytes())).isEqualTo(OBJECT);
}
@Test
public void parseStringShouldReturnObject() throws Exception {
AbstractJsonMarshalTester<Object> tester = createTester(TYPE);
assertThat(tester.parse(JSON)).isEqualTo(OBJECT);
}
@Test
public void readResourcePathShouldReturnObject() throws Exception {
AbstractJsonMarshalTester<Object> tester = createTester(TYPE);
assertThat(tester.read("example.json")).isEqualTo(OBJECT);
}
@Test
public void readFileShouldReturnObject() throws Exception {
File file = this.temp.newFile("example.json");
FileCopyUtils.copy(JSON.getBytes(), file);
AbstractJsonMarshalTester<Object> tester = createTester(TYPE);
assertThat(tester.read(file)).isEqualTo(OBJECT);
}
@Test
public void readInputStreamShouldReturnObject() throws Exception {
InputStream stream = new ByteArrayInputStream(JSON.getBytes());
AbstractJsonMarshalTester<Object> tester = createTester(TYPE);
assertThat(tester.read(stream)).isEqualTo(OBJECT);
}
@Test
public void readResourceShouldReturnObject() throws Exception {
Resource resource = new ByteArrayResource(JSON.getBytes());
AbstractJsonMarshalTester<Object> tester = createTester(TYPE);
assertThat(tester.read(resource)).isEqualTo(OBJECT);
}
@Test
public void readReaderShouldReturnObject() throws Exception {
Reader reader = new StringReader(JSON);
AbstractJsonMarshalTester<Object> tester = createTester(TYPE);
assertThat(tester.read(reader)).isEqualTo(OBJECT);
}
@Test
public void parseListShouldReturnContent() throws Exception {
ResolvableType type = ResolvableTypes.get("listOfExampleObject");
AbstractJsonMarshalTester<Object> tester = createTester(type);
assertThat(tester.parse(ARRAY_JSON)).asList().containsOnly(OBJECT);
}
@Test
public void parseArrayShouldReturnContent() throws Exception {
ResolvableType type = ResolvableTypes.get("arrayOfExampleObject");
AbstractJsonMarshalTester<Object> tester = createTester(type);
assertThat(tester.parse(ARRAY_JSON)).asArray().containsOnly(OBJECT);
}
@Test
public void parseMapShouldReturnContent() throws Exception {
ResolvableType type = ResolvableTypes.get("mapOfExampleObject");
AbstractJsonMarshalTester<Object> tester = createTester(type);
assertThat(tester.parse(MAP_JSON)).asMap().containsEntry("a", OBJECT);
}
protected static final ExampleObject createExampleObject(String name, int age) {
ExampleObject exampleObject = new ExampleObject();
exampleObject.setName(name);
exampleObject.setAge(age);
return exampleObject;
}
protected final AbstractJsonMarshalTester<Object> createTester(ResolvableType type) {
return createTester(AbstractJsonMarshalTesterTests.class, type);
}
protected abstract AbstractJsonMarshalTester<Object> createTester(
Class<?> resourceLoadClass, ResolvableType type);
/**
* Access to field backed {@link ResolvableType}.
*/
public static class ResolvableTypes {
public List<ExampleObject> listOfExampleObject;
public ExampleObject[] arrayOfExampleObject;
public Map<String, ExampleObject> mapOfExampleObject;
public static ResolvableType get(String name) {
Field field = ReflectionUtils.findField(ResolvableTypes.class, name);
return ResolvableType.forField(field);
}
}
}
/*
* Copyright 2012-2016 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.test.json;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.util.FileCopyUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link BasicJsonTester}.
*
* @author Phillip Webb
*/
public class BasicJsonTesterTests {
private static final String JSON = "{\"spring\":[\"boot\",\"framework\"]}";
@Rule
public ExpectedException thrown = ExpectedException.none();
@Rule
public TemporaryFolder tempFolder = new TemporaryFolder();
private BasicJsonTester json = new BasicJsonTester(getClass());
@Test
public void createWhenResourceLoadClassIsNullShouldThrowException() throws Exception {
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("ResourceLoadClass must not be null");
new BasicJsonTester(null);
}
@Test
public void fromJsonStringShouldReturnJsonContent() throws Exception {
assertThat(this.json.from(JSON)).isEqualToJson("source.json");
}
@Test
public void fromResourceStringShouldReturnJsonContent() throws Exception {
assertThat(this.json.from("source.json")).isEqualToJson(JSON);
}
@Test
public void fromResourceStringWithClassShouldReturnJsonContent() throws Exception {
assertThat(this.json.from("source.json", getClass())).isEqualToJson(JSON);
}
@Test
public void fromByteArrayShouldReturnJsonContent() throws Exception {
assertThat(this.json.from(JSON.getBytes())).isEqualToJson("source.json");
}
@Test
public void fromFileShouldReturnJsonContent() throws Exception {
File file = this.tempFolder.newFile("file.json");
FileCopyUtils.copy(JSON.getBytes(), file);
assertThat(this.json.from(file)).isEqualToJson("source.json");
}
@Test
public void fromInputStreamShouldReturnJsonContent() throws Exception {
InputStream inputStream = new ByteArrayInputStream(JSON.getBytes());
assertThat(this.json.from(inputStream)).isEqualToJson("source.json");
}
@Test
public void fromResourceShouldReturnJsonContent() throws Exception {
Resource resource = new ByteArrayResource(JSON.getBytes());
assertThat(this.json.from(resource)).isEqualToJson("source.json");
}
}
/*
* Copyright 2012-2016 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.test.json;
import org.springframework.util.ObjectUtils;
/**
* Example object used for serialization.
*/
public class ExampleObject {
private String name;
private int age;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return this.age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int hashCode() {
return 0;
}
@Override
public boolean equals(Object obj) {
if (obj == null || obj.getClass() != getClass()) {
return false;
}
ExampleObject other = (ExampleObject) obj;
return ObjectUtils.nullSafeEquals(this.name, other.name)
&& ObjectUtils.nullSafeEquals(this.age, other.age);
}
@Override
public String toString() {
return this.name + " " + this.age;
}
}
/*
* Copyright 2012-2016 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.test.json;
import java.util.List;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.junit.Test;
import org.springframework.core.ResolvableType;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link GsonTester}.
*
* @author Phillip Webb
*/
public class GsonTesterTests extends AbstractJsonMarshalTesterTests {
@Test
public void initFieldsWhenTestIsNullShouldThrowException() {
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("TestInstance must not be null");
GsonTester.initFields(null, new GsonBuilder().create());
}
@Test
public void initFieldsWhenObjectMapperIsNullShouldThrowException() {
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("Marshaller must not be null");
GsonTester.initFields(new InitFieldsTestClass(), (Gson) null);
}
@Test
public void initFieldsShouldSetNullFields() {
InitFieldsTestClass test = new InitFieldsTestClass();
assertThat(test.test).isNull();
assertThat(test.base).isNull();
GsonTester.initFields(test, new GsonBuilder().create());
assertThat(test.test).isNotNull();
assertThat(test.base).isNotNull();
assertThat(test.test.getType().resolve()).isEqualTo(List.class);
assertThat(test.test.getType().resolveGeneric()).isEqualTo(ExampleObject.class);
}
@Override
protected AbstractJsonMarshalTester<Object> createTester(Class<?> resourceLoadClass,
ResolvableType type) {
return new GsonTester<Object>(resourceLoadClass, type,
new GsonBuilder().create());
}
static abstract class InitFieldsBaseClass {
public GsonTester<ExampleObject> base;
public GsonTester<ExampleObject> baseSet = new GsonTester<ExampleObject>(
InitFieldsBaseClass.class, ResolvableType.forClass(ExampleObject.class),
new GsonBuilder().create());
}
static class InitFieldsTestClass extends InitFieldsBaseClass {
public GsonTester<List<ExampleObject>> test;
public GsonTester<ExampleObject> testSet = new GsonTester<ExampleObject>(
InitFieldsBaseClass.class, ResolvableType.forClass(ExampleObject.class),
new GsonBuilder().create());
}
}
/*
* Copyright 2012-2016 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.test.json;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Before;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link JacksonTester}. Shows typical usage.
*
* @author Phillip Webb
*/
public class JacksonTesterIntegrationTests {
private JacksonTester<List<ExampleObject>> listJson;
private JacksonTester<Map<String, Integer>> mapJson;
@Before
public void setup() {
JacksonTester.initFields(this, new ObjectMapper());
}
@Test
public void typicalListTest() throws Exception {
String example = "[{\"name\":\"Spring\",\"age\":123}]";
assertThat(this.listJson.parse(example)).asList().hasSize(1);
assertThat(this.listJson.parse(example).getObject().get(0).getName())
.isEqualTo("Spring");
}
@Test
public void typicalMapTest() throws Exception {
Map<String, Integer> map = new LinkedHashMap<String, Integer>();
map.put("a", 1);
map.put("b", 2);
assertThat(this.mapJson.write(map)).extractingJsonPathNumberValue("@.a")
.isEqualTo(1);
}
}
/*
* Copyright 2012-2016 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.test.json;
import java.util.List;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import org.springframework.core.ResolvableType;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link JacksonTester}.
*
* @author Phillip Webb
*/
public class JacksonTesterTests extends AbstractJsonMarshalTesterTests {
@Test
public void initFieldsWhenTestIsNullShouldThrowException() {
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("TestInstance must not be null");
JacksonTester.initFields(null, new ObjectMapper());
}
@Test
public void initFieldsWhenObjectMapperIsNullShouldThrowException() {
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("Marshaller must not be null");
JacksonTester.initFields(new InitFieldsTestClass(), (ObjectMapper) null);
}
@Test
public void initFieldsShouldSetNullFields() {
InitFieldsTestClass test = new InitFieldsTestClass();
assertThat(test.test).isNull();
assertThat(test.base).isNull();
JacksonTester.initFields(test, new ObjectMapper());
assertThat(test.test).isNotNull();
assertThat(test.base).isNotNull();
assertThat(test.test.getType().resolve()).isEqualTo(List.class);
assertThat(test.test.getType().resolveGeneric()).isEqualTo(ExampleObject.class);
}
@Override
protected AbstractJsonMarshalTester<Object> createTester(Class<?> resourceLoadClass,
ResolvableType type) {
return new JacksonTester<Object>(resourceLoadClass, type, new ObjectMapper());
}
static abstract class InitFieldsBaseClass {
public JacksonTester<ExampleObject> base;
public JacksonTester<ExampleObject> baseSet = new JacksonTester<ExampleObject>(
InitFieldsBaseClass.class, ResolvableType.forClass(ExampleObject.class),
new ObjectMapper());
}
static class InitFieldsTestClass extends InitFieldsBaseClass {
public JacksonTester<List<ExampleObject>> test;
public JacksonTester<ExampleObject> testSet = new JacksonTester<ExampleObject>(
InitFieldsBaseClass.class, ResolvableType.forClass(ExampleObject.class),
new ObjectMapper());
}
}
/*
* Copyright 2012-2016 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.test.json;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.core.ResolvableType;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link JsonContent}.
*
* @author Phillip Webb
*/
public class JsonContentTests {
private static final String JSON = "{\"name\":\"spring\", \"age\":100}";
private static final ResolvableType TYPE = ResolvableType
.forClass(ExampleObject.class);
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test
public void createWhenResourceLoadClassIsNullShouldThrowException() throws Exception {
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("ResourceLoadClass must not be null");
new JsonContent<ExampleObject>(null, TYPE, JSON);
}
@Test
public void createThenJsonIsNullShouldThrowException() throws Exception {
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("JSON must not be null");
new JsonContent<ExampleObject>(getClass(), TYPE, null);
}
@Test
public void createWhenTypeIsNullShouldCreateContent() throws Exception {
JsonContent<ExampleObject> content = new JsonContent<ExampleObject>(getClass(),
null, JSON);
assertThat(content).isNotNull();
}
@Test
public void assertThatShouldReturnJsonContentAssert() throws Exception {
JsonContent<ExampleObject> content = new JsonContent<ExampleObject>(getClass(),
TYPE, JSON);
assertThat(content.assertThat()).isInstanceOf(JsonContentAssert.class);
}
@Test
public void getJsonShouldReturnJson() throws Exception {
JsonContent<ExampleObject> content = new JsonContent<ExampleObject>(getClass(),
TYPE, JSON);
assertThat(content.getJson()).isEqualTo(JSON);
}
@Test
public void toStringWhenHasTypeShouldReturnString() throws Exception {
JsonContent<ExampleObject> content = new JsonContent<ExampleObject>(getClass(),
TYPE, JSON);
assertThat(content.toString())
.isEqualTo("JsonContent " + JSON + " created from " + TYPE);
}
@Test
public void toStringWhenNoTypeShouldReturnString() throws Exception {
JsonContent<ExampleObject> content = new JsonContent<ExampleObject>(getClass(),
null, JSON);
assertThat(content.toString()).isEqualTo("JsonContent " + JSON);
}
}
/*
* Copyright 2012-2016 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.test.json;
import java.util.Collections;
import java.util.Map;
import org.assertj.core.api.AssertProvider;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link ObjectContentAssert}.
*
* @author Phillip Webb
*/
public class ObjectContentAssertTests {
private static final ExampleObject SOURCE = new ExampleObject();
private static final ExampleObject DIFFERENT;
static {
DIFFERENT = new ExampleObject();
DIFFERENT.setAge(123);
}
@Test
public void isEqualToWhenObjectsAreEqualShouldPass() throws Exception {
assertThat(forObject(SOURCE)).isEqualTo(SOURCE);
}
@Test(expected = AssertionError.class)
public void isEqualToWhenObjectsAreDifferentShouldFail() throws Exception {
assertThat(forObject(SOURCE)).isEqualTo(DIFFERENT);
}
@Test
public void asArrayForArrayShouldReturnObjectArrayAssert() throws Exception {
ExampleObject[] source = new ExampleObject[] { SOURCE };
assertThat(forObject(source)).asArray().containsExactly(SOURCE);
}
@Test(expected = AssertionError.class)
public void asArrayForNonArrayShouldFail() throws Exception {
assertThat(forObject(SOURCE)).asArray();
}
@Test
public void asMapForMapShouldReturnMapAssert() throws Exception {
Map<String, ExampleObject> source = Collections.singletonMap("a", SOURCE);
assertThat(forObject(source)).asMap().containsEntry("a", SOURCE);
}
@Test(expected = AssertionError.class)
public void asMapForNonMapShouldFail() throws Exception {
assertThat(forObject(SOURCE)).asMap();
}
private AssertProvider<ObjectContentAssert<Object>> forObject(final Object source) {
return new AssertProvider<ObjectContentAssert<Object>>() {
@Override
public ObjectContentAssert<Object> assertThat() {
return new ObjectContentAssert<Object>(source);
}
};
}
}
/*
* Copyright 2012-2016 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.test.json;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.core.ResolvableType;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link ObjectContent}.
*
* @author Phillip Webb
*/
public class ObjectContentTests {
private static final ExampleObject OBJECT = new ExampleObject();
private static final ResolvableType TYPE = ResolvableType
.forClass(ExampleObject.class);
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test
public void createWhenObjectIsNullShouldThrowException() throws Exception {
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("Object must not be null");
new ObjectContent<ExampleObject>(TYPE, null);
}
@Test
public void createWhenTypeIsNullShouldCreateContent() throws Exception {
ObjectContent<ExampleObject> content = new ObjectContent<ExampleObject>(null,
OBJECT);
assertThat(content).isNotNull();
}
@Test
public void assertThatShouldReturnObjectContentAssert() throws Exception {
ObjectContent<ExampleObject> content = new ObjectContent<ExampleObject>(TYPE,
OBJECT);
assertThat(content.assertThat()).isInstanceOf(ObjectContentAssert.class);
}
@Test
public void getObjectShouldReturnObject() throws Exception {
ObjectContent<ExampleObject> content = new ObjectContent<ExampleObject>(TYPE,
OBJECT);
assertThat(content.getObject()).isEqualTo(OBJECT);
}
@Test
public void toStringWhenHasTypeShouldReturnString() throws Exception {
ObjectContent<ExampleObject> content = new ObjectContent<ExampleObject>(TYPE,
OBJECT);
assertThat(content.toString())
.isEqualTo("ObjectContent " + OBJECT + " created from " + TYPE);
}
@Test
public void toStringWhenHasNoTypeShouldReturnString() throws Exception {
ObjectContent<ExampleObject> content = new ObjectContent<ExampleObject>(null,
OBJECT);
assertThat(content.toString()).isEqualTo("ObjectContent " + OBJECT);
}
}
{
"familyMembers":[
{
"name":"Homer"
},
{
"name":"Marge"
},
{
"name":"Bart"
},
{
"name":"Lisa"
},
{
"name":"Maggie"
}
]
}
{
"str":"foo",
"num":5,
"bool":true,
"arr":[
42
],
"colorMap":{
"red":"rojo"
},
"whitespace":" ",
"emptyString":"",
"emptyArray":[
],
"emptyMap":{
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment