Merge pull request #16629 from dberrueta-atlassian

Closes gh-16629:
pull/16730/head
Phillip Webb 6 years ago
commit 7302974751

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -129,7 +129,18 @@ public abstract class AbstractJsonMarshalTester<T> {
verify(); verify();
Assert.notNull(value, "Value must not be null"); Assert.notNull(value, "Value must not be null");
String json = writeObject(value, this.type); String json = writeObject(value, this.type);
return new JsonContent<>(this.resourceLoadClass, this.type, json); return getJsonContent(json);
}
/**
* Factory method used to get a {@link JsonContent} instance from a source JSON
* string.
* @param json the source JSON
* @return a new {@link JsonContent} instance
* @since 2.1.5
*/
protected JsonContent<T> getJsonContent(String json) {
return new JsonContent<>(getResourceLoadClass(), getType(), json);
} }
/** /**

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -24,6 +24,9 @@ import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader; import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.ObjectWriter; import com.fasterxml.jackson.databind.ObjectWriter;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.spi.json.JacksonJsonProvider;
import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider;
import org.springframework.beans.factory.ObjectFactory; import org.springframework.beans.factory.ObjectFactory;
import org.springframework.core.ResolvableType; import org.springframework.core.ResolvableType;
@ -56,6 +59,7 @@ import org.springframework.util.Assert;
* @param <T> the type under test * @param <T> the type under test
* @author Phillip Webb * @author Phillip Webb
* @author Madhura Bhave * @author Madhura Bhave
* @author Diego Berrueta
* @since 1.4.0 * @since 1.4.0
*/ */
public class JacksonTester<T> extends AbstractJsonMarshalTester<T> { public class JacksonTester<T> extends AbstractJsonMarshalTester<T> {
@ -92,6 +96,14 @@ public class JacksonTester<T> extends AbstractJsonMarshalTester<T> {
this.view = view; this.view = view;
} }
@Override
protected JsonContent<T> getJsonContent(String json) {
Configuration configuration = Configuration.builder()
.jsonProvider(new JacksonJsonProvider(this.objectMapper))
.mappingProvider(new JacksonMappingProvider(this.objectMapper)).build();
return new JsonContent<>(getResourceLoadClass(), getType(), json, configuration);
}
@Override @Override
protected T readObject(InputStream inputStream, ResolvableType type) protected T readObject(InputStream inputStream, ResolvableType type)
throws IOException { throws IOException {

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,6 +16,7 @@
package org.springframework.boot.test.json; package org.springframework.boot.test.json;
import com.jayway.jsonpath.Configuration;
import org.assertj.core.api.AssertProvider; import org.assertj.core.api.AssertProvider;
import org.springframework.core.ResolvableType; import org.springframework.core.ResolvableType;
@ -28,6 +29,7 @@ import org.springframework.util.Assert;
* *
* @param <T> the source type that created the content * @param <T> the source type that created the content
* @author Phillip Webb * @author Phillip Webb
* @author Diego Berrueta
* @since 1.4.0 * @since 1.4.0
*/ */
public final class JsonContent<T> implements AssertProvider<JsonContentAssert> { public final class JsonContent<T> implements AssertProvider<JsonContentAssert> {
@ -38,6 +40,8 @@ public final class JsonContent<T> implements AssertProvider<JsonContentAssert> {
private final String json; private final String json;
private final Configuration configuration;
/** /**
* Create a new {@link JsonContent} instance. * Create a new {@link JsonContent} instance.
* @param resourceLoadClass the source class used to load resources * @param resourceLoadClass the source class used to load resources
@ -45,11 +49,25 @@ public final class JsonContent<T> implements AssertProvider<JsonContentAssert> {
* @param json the actual JSON content * @param json the actual JSON content
*/ */
public JsonContent(Class<?> resourceLoadClass, ResolvableType type, String json) { public JsonContent(Class<?> resourceLoadClass, ResolvableType type, String json) {
this(resourceLoadClass, type, json, Configuration.defaultConfiguration());
}
/**
* 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
* @param configuration the JsonPath configuration
*/
JsonContent(Class<?> resourceLoadClass, ResolvableType type, String json,
Configuration configuration) {
Assert.notNull(resourceLoadClass, "ResourceLoadClass must not be null"); Assert.notNull(resourceLoadClass, "ResourceLoadClass must not be null");
Assert.notNull(json, "JSON must not be null"); Assert.notNull(json, "JSON must not be null");
Assert.notNull(configuration, "Configuration must not be null");
this.resourceLoadClass = resourceLoadClass; this.resourceLoadClass = resourceLoadClass;
this.type = type; this.type = type;
this.json = json; this.json = json;
this.configuration = configuration;
} }
/** /**
@ -61,7 +79,8 @@ public final class JsonContent<T> implements AssertProvider<JsonContentAssert> {
@Override @Override
@Deprecated @Deprecated
public JsonContentAssert assertThat() { public JsonContentAssert assertThat() {
return new JsonContentAssert(this.resourceLoadClass, this.json); return new JsonContentAssert(this.resourceLoadClass, null, this.json,
this.configuration);
} }
/** /**

@ -22,6 +22,7 @@ import java.nio.charset.Charset;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPath; import com.jayway.jsonpath.JsonPath;
import org.assertj.core.api.AbstractAssert; import org.assertj.core.api.AbstractAssert;
import org.assertj.core.api.AbstractBooleanAssert; import org.assertj.core.api.AbstractBooleanAssert;
@ -45,12 +46,15 @@ import org.springframework.util.StringUtils;
* *
* @author Phillip Webb * @author Phillip Webb
* @author Andy Wilkinson * @author Andy Wilkinson
* @author Diego Berrueta
* @since 1.4.0 * @since 1.4.0
*/ */
public class JsonContentAssert extends AbstractAssert<JsonContentAssert, CharSequence> { public class JsonContentAssert extends AbstractAssert<JsonContentAssert, CharSequence> {
private final JsonLoader loader; private final JsonLoader loader;
private final Configuration configuration;
/** /**
* Create a new {@link JsonContentAssert} instance that will load resources as UTF-8. * Create a new {@link JsonContentAssert} instance that will load resources as UTF-8.
* @param resourceLoadClass the source class used to load resources * @param resourceLoadClass the source class used to load resources
@ -70,7 +74,21 @@ public class JsonContentAssert extends AbstractAssert<JsonContentAssert, CharSeq
*/ */
public JsonContentAssert(Class<?> resourceLoadClass, Charset charset, public JsonContentAssert(Class<?> resourceLoadClass, Charset charset,
CharSequence json) { CharSequence json) {
this(resourceLoadClass, charset, json, Configuration.defaultConfiguration());
}
/**
* Create a new {@link JsonContentAssert} instance that will load resources in the
* given {@code charset}.
* @param resourceLoadClass the source class used to load resources
* @param charset the charset of the JSON resources
* @param json the actual JSON content
* @param configuration the json-path configuration
*/
JsonContentAssert(Class<?> resourceLoadClass, Charset charset, CharSequence json,
Configuration configuration) {
super(json, JsonContentAssert.class); super(json, JsonContentAssert.class);
this.configuration = configuration;
this.loader = new JsonLoader(resourceLoadClass, charset); this.loader = new JsonLoader(resourceLoadClass, charset);
} }
@ -1109,7 +1127,8 @@ public class JsonContentAssert extends AbstractAssert<JsonContentAssert, CharSeq
public Object getValue(boolean required) { public Object getValue(boolean required) {
try { try {
CharSequence json = JsonContentAssert.this.actual; CharSequence json = JsonContentAssert.this.actual;
return this.jsonPath.read((json != null) ? json.toString() : null); return this.jsonPath.read((json != null) ? json.toString() : null,
JsonContentAssert.this.configuration);
} }
catch (Exception ex) { catch (Exception ex) {
if (!required) { if (!required) {

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

@ -0,0 +1,87 @@
/*
* Copyright 2012-2019 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
*
* https://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.google.gson.Gson;
import org.junit.Before;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link GsonTester}. Shows typical usage.
*
* @author Andy Wilkinson
* @author Diego Berrueta
*/
public class GsonTesterIntegrationTests {
private GsonTester<ExampleObject> simpleJson;
private GsonTester<List<ExampleObject>> listJson;
private GsonTester<Map<String, Integer>> mapJson;
private GsonTester<String> stringJson;
private Gson gson;
private static final String JSON = "{\"name\":\"Spring\",\"age\":123}";
@Before
public void setup() {
this.gson = new Gson();
GsonTester.initFields(this, this.gson);
}
@Test
public void typicalTest() throws Exception {
String example = JSON;
assertThat(this.simpleJson.parse(example).getObject().getName())
.isEqualTo("Spring");
}
@Test
public void typicalListTest() throws Exception {
String example = "[" + JSON + "]";
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<>();
map.put("a", 1);
map.put("b", 2);
assertThat(this.mapJson.write(map)).extractingJsonPathNumberValue("@.a")
.isEqualTo(1);
}
@Test
public void stringLiteral() throws Exception {
String stringWithSpecialCharacters = "myString";
assertThat(this.stringJson.write(stringWithSpecialCharacters))
.extractingJsonPathStringValue("@")
.isEqualTo(stringWithSpecialCharacters);
}
}

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -36,6 +36,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* *
* @author Phillip Webb * @author Phillip Webb
* @author Madhura Bhave * @author Madhura Bhave
* @author Diego Berrueta
*/ */
public class JacksonTesterIntegrationTests { public class JacksonTesterIntegrationTests {
@ -47,6 +48,8 @@ public class JacksonTesterIntegrationTests {
private JacksonTester<Map<String, Integer>> mapJson; private JacksonTester<Map<String, Integer>> mapJson;
private JacksonTester<String> stringJson;
private ObjectMapper objectMapper; private ObjectMapper objectMapper;
private static final String JSON = "{\"name\":\"Spring\",\"age\":123}"; private static final String JSON = "{\"name\":\"Spring\",\"age\":123}";
@ -81,6 +84,28 @@ public class JacksonTesterIntegrationTests {
.isEqualTo(1); .isEqualTo(1);
} }
@Test
public void stringLiteral() throws Exception {
String stringWithSpecialCharacters = "myString";
assertThat(this.stringJson.write(stringWithSpecialCharacters))
.extractingJsonPathStringValue("@")
.isEqualTo(stringWithSpecialCharacters);
}
@Test
public void parseSpecialCharactersTest() throws Exception {
// Confirms that the handling of special characters is symmetrical between
// the serialization (via the JacksonTester) and the parsing (via json-path). By
// default json-path uses SimpleJson as its parser, which has a slightly different
// behavior to Jackson and breaks the symmetry. JacksonTester
// configures json-path to use Jackson for evaluating the path expressions and
// restores the symmetry. See gh-15727
String stringWithSpecialCharacters = "\u0006\u007F";
assertThat(this.stringJson.write(stringWithSpecialCharacters))
.extractingJsonPathStringValue("@")
.isEqualTo(stringWithSpecialCharacters);
}
@Test @Test
public void writeWithView() throws Exception { public void writeWithView() throws Exception {
this.objectMapper.disable(MapperFeature.DEFAULT_VIEW_INCLUSION); this.objectMapper.disable(MapperFeature.DEFAULT_VIEW_INCLUSION);

@ -16,6 +16,7 @@
package org.springframework.boot.test.json; package org.springframework.boot.test.json;
import com.jayway.jsonpath.Configuration;
import org.junit.Test; import org.junit.Test;
import org.springframework.core.ResolvableType; import org.springframework.core.ResolvableType;
@ -38,47 +39,61 @@ public class JsonContentTests {
@Test @Test
public void createWhenResourceLoadClassIsNullShouldThrowException() { public void createWhenResourceLoadClassIsNullShouldThrowException() {
assertThatIllegalArgumentException() assertThatIllegalArgumentException()
.isThrownBy(() -> new JsonContent<ExampleObject>(null, TYPE, JSON)) .isThrownBy(() -> new JsonContent<ExampleObject>(null, TYPE, JSON,
Configuration.defaultConfiguration()))
.withMessageContaining("ResourceLoadClass must not be null"); .withMessageContaining("ResourceLoadClass must not be null");
} }
@Test @Test
public void createWhenJsonIsNullShouldThrowException() { public void createWhenJsonIsNullShouldThrowException() {
assertThatIllegalArgumentException() assertThatIllegalArgumentException()
.isThrownBy(() -> new JsonContent<ExampleObject>(getClass(), TYPE, null)) .isThrownBy(() -> new JsonContent<ExampleObject>(getClass(), TYPE, null,
Configuration.defaultConfiguration()))
.withMessageContaining("JSON must not be null"); .withMessageContaining("JSON must not be null");
} }
@Test
public void createWhenConfigurationIsNullShouldThrowException() {
assertThatIllegalArgumentException().isThrownBy(
() -> new JsonContent<ExampleObject>(getClass(), TYPE, JSON, null))
.withMessageContaining("Configuration must not be null");
}
@Test @Test
public void createWhenTypeIsNullShouldCreateContent() { public void createWhenTypeIsNullShouldCreateContent() {
JsonContent<ExampleObject> content = new JsonContent<>(getClass(), null, JSON); JsonContent<ExampleObject> content = new JsonContent<>(getClass(), null, JSON,
Configuration.defaultConfiguration());
assertThat(content).isNotNull(); assertThat(content).isNotNull();
} }
@Test @Test
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public void assertThatShouldReturnJsonContentAssert() { public void assertThatShouldReturnJsonContentAssert() {
JsonContent<ExampleObject> content = new JsonContent<>(getClass(), TYPE, JSON); JsonContent<ExampleObject> content = new JsonContent<>(getClass(), TYPE, JSON,
Configuration.defaultConfiguration());
assertThat(content.assertThat()).isInstanceOf(JsonContentAssert.class); assertThat(content.assertThat()).isInstanceOf(JsonContentAssert.class);
} }
@Test @Test
public void getJsonShouldReturnJson() { public void getJsonShouldReturnJson() {
JsonContent<ExampleObject> content = new JsonContent<>(getClass(), TYPE, JSON); JsonContent<ExampleObject> content = new JsonContent<>(getClass(), TYPE, JSON,
Configuration.defaultConfiguration());
assertThat(content.getJson()).isEqualTo(JSON); assertThat(content.getJson()).isEqualTo(JSON);
} }
@Test @Test
public void toStringWhenHasTypeShouldReturnString() { public void toStringWhenHasTypeShouldReturnString() {
JsonContent<ExampleObject> content = new JsonContent<>(getClass(), TYPE, JSON); JsonContent<ExampleObject> content = new JsonContent<>(getClass(), TYPE, JSON,
Configuration.defaultConfiguration());
assertThat(content.toString()) assertThat(content.toString())
.isEqualTo("JsonContent " + JSON + " created from " + TYPE); .isEqualTo("JsonContent " + JSON + " created from " + TYPE);
} }
@Test @Test
public void toStringWhenHasNoTypeShouldReturnString() { public void toStringWhenHasNoTypeShouldReturnString() {
JsonContent<ExampleObject> content = new JsonContent<>(getClass(), null, JSON); JsonContent<ExampleObject> content = new JsonContent<>(getClass(), null, JSON,
Configuration.defaultConfiguration());
assertThat(content.toString()).isEqualTo("JsonContent " + JSON); assertThat(content.toString()).isEqualTo("JsonContent " + JSON);
} }

Loading…
Cancel
Save