Merge JSON assertions in a single Assert type
This commit merges the JSONCompare and JsonPath support in a single assert object. The rationale for the previous situation was that JsonPath is optional but merging the assertions methods do not make it mandatory as the usage if JsonPath is triggered only if it is actually used. See gh-32712
This commit is contained in:
@@ -0,0 +1,781 @@
|
||||
/*
|
||||
* Copyright 2002-2024 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.test.json;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.assertj.core.api.AssertProvider;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.junit.jupiter.api.TestInstance.Lifecycle;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.skyscreamer.jsonassert.JSONCompareMode;
|
||||
import org.skyscreamer.jsonassert.comparator.DefaultComparator;
|
||||
import org.skyscreamer.jsonassert.comparator.JSONComparator;
|
||||
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.core.io.InputStreamResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.http.converter.GenericHttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
import static org.assertj.core.api.Assertions.entry;
|
||||
|
||||
/**
|
||||
* Tests for {@link AbstractJsonContentAssert}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class AbstractJsonContentAssertTests {
|
||||
|
||||
private static final String TYPES = loadJson("types.json");
|
||||
|
||||
private static final String SIMPSONS = loadJson("simpsons.json");
|
||||
|
||||
private static final String NULLS = loadJson("nulls.json");
|
||||
|
||||
private static final String SOURCE = loadJson("source.json");
|
||||
|
||||
private static final String LENIENT_SAME = loadJson("lenient-same.json");
|
||||
|
||||
private static final String DIFFERENT = loadJson("different.json");
|
||||
|
||||
private static final MappingJackson2HttpMessageConverter jsonHttpMessageConverter =
|
||||
new MappingJackson2HttpMessageConverter(new ObjectMapper());
|
||||
|
||||
private static final JSONComparator comparator = new DefaultComparator(JSONCompareMode.LENIENT);
|
||||
|
||||
@Test
|
||||
void isNullWhenActualIsNullShouldPass() {
|
||||
assertThat(forJson(null)).isNull();
|
||||
}
|
||||
|
||||
@Nested
|
||||
class HasPathTests {
|
||||
|
||||
@Test
|
||||
void hasPathForNullJson() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(null)).hasPath("no"))
|
||||
.withMessageContaining("Expecting actual not to be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void hasPathForPresentAndNotNull() {
|
||||
assertThat(forJson(NULLS)).hasPath("$.valuename");
|
||||
}
|
||||
|
||||
@Test
|
||||
void hasPathForPresentAndNull() {
|
||||
assertThat(forJson(NULLS)).hasPath("$.nullname");
|
||||
}
|
||||
|
||||
@Test
|
||||
void hasPathForOperatorMatching() {
|
||||
assertThat(forJson(SIMPSONS)).
|
||||
hasPath("$.familyMembers[?(@.name == 'Homer')]");
|
||||
}
|
||||
|
||||
@Test
|
||||
void hasPathForOperatorNotMatching() {
|
||||
assertThat(forJson(SIMPSONS)).
|
||||
hasPath("$.familyMembers[?(@.name == 'Dilbert')]");
|
||||
}
|
||||
|
||||
@Test
|
||||
void hasPathForNotPresent() {
|
||||
String expression = "$.missing";
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(NULLS)).hasPath(expression))
|
||||
.satisfies(hasFailedToMatchPath("$.missing"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void hasPathSatisfying() {
|
||||
assertThat(forJson(TYPES)).hasPathSatisfying("$.str", value -> assertThat(value).isEqualTo("foo"))
|
||||
.hasPathSatisfying("$.num", value -> assertThat(value).isEqualTo(5));
|
||||
}
|
||||
|
||||
@Test
|
||||
void hasPathSatisfyingForPathNotPresent() {
|
||||
String expression = "missing";
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(NULLS)).hasPathSatisfying(expression, value -> {}))
|
||||
.satisfies(hasFailedToMatchPath(expression));
|
||||
}
|
||||
|
||||
@Test
|
||||
void doesNotHavePathForMissing() {
|
||||
assertThat(forJson(NULLS)).doesNotHavePath("$.missing");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void doesNotHavePathForPresent() {
|
||||
String expression = "$.valuename";
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(NULLS)).doesNotHavePath(expression))
|
||||
.satisfies(hasFailedToNotMatchPath(expression));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nested
|
||||
class ExtractingPathTests {
|
||||
|
||||
@Test
|
||||
void extractingPathForNullJson() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(null)).extractingPath("$"))
|
||||
.withMessageContaining("Expecting actual not to be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNullWithNullPathValue() {
|
||||
assertThat(forJson(NULLS)).extractingPath("$.nullname").isNull();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = { "$.str", "$.emptyString", "$.num", "$.bool", "$.arr",
|
||||
"$.emptyArray", "$.colorMap", "$.emptyMap" })
|
||||
void isNotNullWithValue(String path) {
|
||||
assertThat(forJson(TYPES)).extractingPath(path).isNotNull();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
void isEqualToOnRawValue(String path, Object expected) {
|
||||
assertThat(forJson(TYPES)).extractingPath(path).isEqualTo(expected);
|
||||
}
|
||||
|
||||
static Stream<Arguments> isEqualToOnRawValue() {
|
||||
return Stream.of(
|
||||
Arguments.of("$.str", "foo"),
|
||||
Arguments.of("$.num", 5),
|
||||
Arguments.of("$.bool", true),
|
||||
Arguments.of("$.arr", List.of(42)),
|
||||
Arguments.of("$.colorMap", Map.of("red", "rojo")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void asStringWithActualValue() {
|
||||
assertThat(forJson(TYPES)).extractingPath("@.str").asString().startsWith("f").endsWith("o");
|
||||
}
|
||||
|
||||
@Test
|
||||
void asStringIsEmpty() {
|
||||
assertThat(forJson(TYPES)).extractingPath("@.emptyString").asString().isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void asNumberWithActualValue() {
|
||||
assertThat(forJson(TYPES)).extractingPath("@.num").asNumber().isEqualTo(5);
|
||||
}
|
||||
|
||||
@Test
|
||||
void asBooleanWithActualValue() {
|
||||
assertThat(forJson(TYPES)).extractingPath("@.bool").asBoolean().isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void asArrayWithActualValue() {
|
||||
assertThat(forJson(TYPES)).extractingPath("@.arr").asArray().containsOnly(42);
|
||||
}
|
||||
|
||||
@Test
|
||||
void asArrayIsEmpty() {
|
||||
assertThat(forJson(TYPES)).extractingPath("@.emptyArray").asArray().isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void asArrayWithFilterPredicatesMatching() {
|
||||
assertThat(forJson(SIMPSONS))
|
||||
.extractingPath("$.familyMembers[?(@.name == 'Bart')]").asArray().hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void asArrayWithFilterPredicatesNotMatching() {
|
||||
assertThat(forJson(SIMPSONS)).
|
||||
extractingPath("$.familyMembers[?(@.name == 'Dilbert')]").asArray().isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void asMapWithActualValue() {
|
||||
assertThat(forJson(TYPES)).extractingPath("@.colorMap").asMap().containsOnly(entry("red", "rojo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void asMapIsEmpty() {
|
||||
assertThat(forJson(TYPES)).extractingPath("@.emptyMap").asMap().isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void convertToWithoutHttpMessageConverterShouldFail() {
|
||||
JsonPathValueAssert path = assertThat(forJson(SIMPSONS)).extractingPath("$.familyMembers[0]");
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> path.convertTo(ExtractingPathTests.Member.class))
|
||||
.withMessage("No JSON message converter available to convert {name=Homer}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void convertToTargetType() {
|
||||
assertThat(forJson(SIMPSONS, jsonHttpMessageConverter))
|
||||
.extractingPath("$.familyMembers[0]").convertTo(ExtractingPathTests.Member.class)
|
||||
.satisfies(member -> assertThat(member.name).isEqualTo("Homer"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void convertToIncompatibleTargetTypeShouldFail() {
|
||||
JsonPathValueAssert path = assertThat(forJson(SIMPSONS, jsonHttpMessageConverter))
|
||||
.extractingPath("$.familyMembers[0]");
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> path.convertTo(ExtractingPathTests.Customer.class))
|
||||
.withMessageContainingAll("Expected value at JSON path \"$.familyMembers[0]\":",
|
||||
Customer.class.getName(), "name");
|
||||
}
|
||||
|
||||
@Test
|
||||
void convertArrayToParameterizedType() {
|
||||
assertThat(forJson(SIMPSONS, jsonHttpMessageConverter))
|
||||
.extractingPath("$.familyMembers")
|
||||
.convertTo(new ParameterizedTypeReference<List<Member>>() {})
|
||||
.satisfies(family -> assertThat(family).hasSize(5).element(0).isEqualTo(new Member("Homer")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEmptyWithPathHavingNullValue() {
|
||||
assertThat(forJson(NULLS)).extractingPath("nullname").isEmpty();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = { "$.emptyString", "$.emptyArray", "$.emptyMap" })
|
||||
void isEmptyWithEmptyValue(String path) {
|
||||
assertThat(forJson(TYPES)).extractingPath(path).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEmptyForPathWithFilterMatching() {
|
||||
String expression = "$.familyMembers[?(@.name == 'Bart')]";
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SIMPSONS)).extractingPath(expression).isEmpty())
|
||||
.withMessageContainingAll("Expected value at JSON path \"" + expression + "\"",
|
||||
"[{\"name\":\"Bart\"}]", "To be empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEmptyForPathWithFilterNotMatching() {
|
||||
assertThat(forJson(SIMPSONS)).extractingPath("$.familyMembers[?(@.name == 'Dilbert')]").isEmpty();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = { "$.str", "$.num", "$.bool", "$.arr", "$.colorMap" })
|
||||
void isNotEmptyWithNonNullValue(String path) {
|
||||
assertThat(forJson(TYPES)).extractingPath(path).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEmptyForPathWithFilterMatching() {
|
||||
assertThat(forJson(SIMPSONS)).extractingPath("$.familyMembers[?(@.name == 'Bart')]").isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEmptyForPathWithFilterNotMatching() {
|
||||
String expression = "$.familyMembers[?(@.name == 'Dilbert')]";
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SIMPSONS)).extractingPath(expression).isNotEmpty())
|
||||
.withMessageContainingAll("Expected value at JSON path \"" + expression + "\"",
|
||||
"To not be empty");
|
||||
}
|
||||
|
||||
|
||||
private record Member(String name) {}
|
||||
|
||||
private record Customer(long id, String username) {}
|
||||
|
||||
private AssertProvider<AbstractJsonContentAssert<?>> forJson(@Nullable String json) {
|
||||
return () -> new TestJsonContentAssert(json, null, null, null);
|
||||
}
|
||||
|
||||
private AssertProvider<AbstractJsonContentAssert<?>> forJson(@Nullable String json, GenericHttpMessageConverter<Object> jsonHttpMessageConverter) {
|
||||
return () -> new TestJsonContentAssert(json, jsonHttpMessageConverter, null, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nested
|
||||
class EqualsNotEqualsTests {
|
||||
|
||||
@Test
|
||||
void isEqualToWhenStringIsMatchingShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isEqualTo(SOURCE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEqualToWhenNullActualShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertThat(forJson(null)).isEqualTo(SOURCE));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEqualToWhenExpectedIsNotAStringShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isEqualTo(SOURCE.getBytes()));
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestInstance(Lifecycle.PER_CLASS)
|
||||
class JsonAssertTests {
|
||||
|
||||
@Test
|
||||
void isEqualToWhenExpectedIsNullShouldFail() {
|
||||
CharSequence actual = null;
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isEqualTo(actual, JSONCompareMode.LENIENT));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEqualToWhenStringIsMatchingAndLenientShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isEqualTo(LENIENT_SAME, JSONCompareMode.LENIENT);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEqualToWhenStringIsNotMatchingAndLenientShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isEqualTo(DIFFERENT, JSONCompareMode.LENIENT));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEqualToWhenResourcePathIsMatchingAndLenientShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isEqualTo("lenient-same.json", JSONCompareMode.LENIENT);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEqualToWhenResourcePathIsNotMatchingAndLenientShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isEqualTo("different.json", JSONCompareMode.LENIENT));
|
||||
}
|
||||
|
||||
Stream<Arguments> source() {
|
||||
return Stream.of(
|
||||
Arguments.of(new ClassPathResource("source.json", AbstractJsonContentAssertTests.class)),
|
||||
Arguments.of(new ByteArrayResource(SOURCE.getBytes())),
|
||||
Arguments.of(new FileSystemResource(createFile(SOURCE))),
|
||||
Arguments.of(new InputStreamResource(createInputStream(SOURCE))));
|
||||
}
|
||||
|
||||
Stream<Arguments> lenientSame() {
|
||||
return Stream.of(
|
||||
Arguments.of(new ClassPathResource("lenient-same.json", AbstractJsonContentAssertTests.class)),
|
||||
Arguments.of(new ByteArrayResource(LENIENT_SAME.getBytes())),
|
||||
Arguments.of(new FileSystemResource(createFile(LENIENT_SAME))),
|
||||
Arguments.of(new InputStreamResource(createInputStream(LENIENT_SAME))));
|
||||
}
|
||||
|
||||
Stream<Arguments> different() {
|
||||
return Stream.of(
|
||||
Arguments.of(new ClassPathResource("different.json", AbstractJsonContentAssertTests.class)),
|
||||
Arguments.of(new ByteArrayResource(DIFFERENT.getBytes())),
|
||||
Arguments.of(new FileSystemResource(createFile(DIFFERENT))),
|
||||
Arguments.of(new InputStreamResource(createInputStream(DIFFERENT))));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("lenientSame")
|
||||
void isEqualToWhenResourceIsMatchingAndLenientSameShouldPass(Resource expected) {
|
||||
assertThat(forJson(SOURCE)).isEqualTo(expected, JSONCompareMode.LENIENT);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("different")
|
||||
void isEqualToWhenResourceIsNotMatchingAndLenientShouldFail(Resource expected) {
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(
|
||||
() -> assertThat(forJson(SOURCE)).isEqualTo(expected, JSONCompareMode.LENIENT));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEqualToWhenStringIsMatchingAndComparatorShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isEqualTo(LENIENT_SAME, comparator);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEqualToWhenStringIsNotMatchingAndComparatorShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isEqualTo(DIFFERENT, comparator));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEqualToWhenResourcePathIsMatchingAndComparatorShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isEqualTo("lenient-same.json", comparator);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEqualToWhenResourcePathIsNotMatchingAndComparatorShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isEqualTo("different.json", comparator));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("lenientSame")
|
||||
void isEqualToWhenResourceIsMatchingAndComparatorShouldPass(Resource expected) {
|
||||
assertThat(forJson(SOURCE)).isEqualTo(expected, comparator);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("different")
|
||||
void isEqualToWhenResourceIsNotMatchingAndComparatorShouldFail(Resource expected) {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isEqualTo(expected, comparator));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isLenientlyEqualToWhenStringIsMatchingShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isLenientlyEqualTo(LENIENT_SAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isLenientlyEqualToWhenNullActualShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(null)).isLenientlyEqualTo(SOURCE));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isLenientlyEqualToWhenStringIsNotMatchingShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isLenientlyEqualTo(DIFFERENT));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isLenientlyEqualToWhenExpectedDoesNotExistShouldFail() {
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isLenientlyEqualTo("does-not-exist.json"))
|
||||
.withMessage("Unable to load JSON from class path resource [org/springframework/test/json/does-not-exist.json]");
|
||||
}
|
||||
|
||||
@Test
|
||||
void isLenientlyEqualToWhenResourcePathIsMatchingShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isLenientlyEqualTo("lenient-same.json");
|
||||
}
|
||||
|
||||
@Test
|
||||
void isLenientlyEqualToWhenResourcePathIsNotMatchingShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isLenientlyEqualTo("different.json"));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("lenientSame")
|
||||
void isLenientlyEqualToWhenResourceIsMatchingShouldPass(Resource expected) {
|
||||
assertThat(forJson(SOURCE)).isLenientlyEqualTo(expected);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("different")
|
||||
void isLenientlyEqualToWhenResourceIsNotMatchingShouldFail(Resource expected) {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isLenientlyEqualTo(expected));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isStrictlyEqualToWhenStringIsMatchingShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isStrictlyEqualTo(SOURCE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isStrictlyEqualToWhenStringIsNotMatchingShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isStrictlyEqualTo(LENIENT_SAME));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isStrictlyEqualToWhenResourcePathIsMatchingShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isStrictlyEqualTo("source.json");
|
||||
}
|
||||
|
||||
@Test
|
||||
void isStrictlyEqualToWhenResourcePathIsNotMatchingShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isStrictlyEqualTo("lenient-same.json"));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("source")
|
||||
void isStrictlyEqualToWhenResourceIsMatchingShouldPass(Resource expected) {
|
||||
assertThat(forJson(SOURCE)).isStrictlyEqualTo(expected);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("lenientSame")
|
||||
void isStrictlyEqualToWhenResourceIsNotMatchingShouldFail(Resource expected) {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isStrictlyEqualTo(expected));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void isNotEqualToWhenStringIsMatchingShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isNotEqualTo(SOURCE));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEqualToWhenNullActualShouldPass() {
|
||||
assertThat(forJson(null)).isNotEqualTo(SOURCE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEqualToWhenStringIsNotMatchingShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isNotEqualTo(DIFFERENT);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEqualToAsObjectWhenExpectedIsNotAStringShouldNotFail() {
|
||||
assertThat(forJson(SOURCE)).isNotEqualTo(SOURCE.getBytes());
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEqualToWhenStringIsMatchingAndLenientShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isNotEqualTo(LENIENT_SAME, JSONCompareMode.LENIENT));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEqualToWhenStringIsNotMatchingAndLenientShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isNotEqualTo(DIFFERENT, JSONCompareMode.LENIENT);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEqualToWhenResourcePathIsMatchingAndLenientShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(
|
||||
() -> assertThat(forJson(SOURCE)).isNotEqualTo("lenient-same.json", JSONCompareMode.LENIENT));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEqualToWhenResourcePathIsNotMatchingAndLenientShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isNotEqualTo("different.json", JSONCompareMode.LENIENT);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("lenientSame")
|
||||
void isNotEqualToWhenResourceIsMatchingAndLenientShouldFail(Resource expected) {
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> assertThat(forJson(SOURCE))
|
||||
.isNotEqualTo(expected, JSONCompareMode.LENIENT));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("different")
|
||||
void isNotEqualToWhenResourceIsNotMatchingAndLenientShouldPass(Resource expected) {
|
||||
assertThat(forJson(SOURCE)).isNotEqualTo(expected, JSONCompareMode.LENIENT);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEqualToWhenStringIsMatchingAndComparatorShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isNotEqualTo(LENIENT_SAME, comparator));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEqualToWhenStringIsNotMatchingAndComparatorShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isNotEqualTo(DIFFERENT, comparator);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEqualToWhenResourcePathIsMatchingAndComparatorShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isNotEqualTo("lenient-same.json", comparator));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEqualToWhenResourcePathIsNotMatchingAndComparatorShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isNotEqualTo("different.json", comparator);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("lenientSame")
|
||||
void isNotEqualToWhenResourceIsMatchingAndComparatorShouldFail(Resource expected) {
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(
|
||||
() -> assertThat(forJson(SOURCE)).isNotEqualTo(expected, comparator));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("different")
|
||||
void isNotEqualToWhenResourceIsNotMatchingAndComparatorShouldPass(Resource expected) {
|
||||
assertThat(forJson(SOURCE)).isNotEqualTo(expected, comparator);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEqualToWhenResourceIsMatchingAndComparatorShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isNotEqualTo(createResource(LENIENT_SAME), comparator));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEqualToWhenResourceIsNotMatchingAndComparatorShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isNotEqualTo(createResource(DIFFERENT), comparator);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotLenientlyEqualToWhenNullActualShouldPass() {
|
||||
assertThat(forJson(null)).isNotLenientlyEqualTo(SOURCE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotLenientlyEqualToWhenStringIsNotMatchingShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isNotLenientlyEqualTo(DIFFERENT);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotLenientlyEqualToWhenResourcePathIsMatchingShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isNotLenientlyEqualTo("lenient-same.json"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotLenientlyEqualToWhenResourcePathIsNotMatchingShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isNotLenientlyEqualTo("different.json");
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("lenientSame")
|
||||
void isNotLenientlyEqualToWhenResourceIsMatchingShouldFail(Resource expected) {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isNotLenientlyEqualTo(expected));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("different")
|
||||
void isNotLenientlyEqualToWhenResourceIsNotMatchingShouldPass(Resource expected) {
|
||||
assertThat(forJson(SOURCE)).isNotLenientlyEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotStrictlyEqualToWhenStringIsMatchingShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isNotStrictlyEqualTo(SOURCE));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotStrictlyEqualToWhenStringIsNotMatchingShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isNotStrictlyEqualTo(LENIENT_SAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotStrictlyEqualToWhenResourcePathIsMatchingShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isNotStrictlyEqualTo("source.json"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotStrictlyEqualToWhenResourcePathIsNotMatchingShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isNotStrictlyEqualTo("lenient-same.json");
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("source")
|
||||
void isNotStrictlyEqualToWhenResourceIsMatchingShouldFail(Resource expected) {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isNotStrictlyEqualTo(expected));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("lenientSame")
|
||||
void isNotStrictlyEqualToWhenResourceIsNotMatchingShouldPass(Resource expected) {
|
||||
assertThat(forJson(SOURCE)).isNotStrictlyEqualTo(expected);
|
||||
}
|
||||
|
||||
private AssertProvider<AbstractJsonContentAssert<?>> forJson(@Nullable String json) {
|
||||
return () -> new TestJsonContentAssert(json, null, getClass(), null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private Consumer<AssertionError> hasFailedToMatchPath(String expression) {
|
||||
return error -> assertThat(error.getMessage()).containsSubsequence("Expecting:",
|
||||
"To match JSON path:", "\"" + expression + "\"");
|
||||
}
|
||||
|
||||
private Consumer<AssertionError> hasFailedToNotMatchPath(String expression) {
|
||||
return error -> assertThat(error.getMessage()).containsSubsequence("Expecting:",
|
||||
"Not to match JSON path:", "\"" + expression + "\"");
|
||||
}
|
||||
|
||||
private Path createFile(String content) {
|
||||
try {
|
||||
Path temp = Files.createTempFile("file", ".json");
|
||||
Files.writeString(temp, content);
|
||||
return temp;
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private InputStream createInputStream(String content) {
|
||||
return new ByteArrayInputStream(content.getBytes());
|
||||
}
|
||||
|
||||
private Resource createResource(String content) {
|
||||
return new ByteArrayResource(content.getBytes());
|
||||
}
|
||||
|
||||
private static String loadJson(String path) {
|
||||
try {
|
||||
ClassPathResource resource = new ClassPathResource(path, AbstractJsonContentAssertTests.class);
|
||||
return new String(FileCopyUtils.copyToByteArray(resource.getInputStream()));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private AssertProvider<AbstractJsonContentAssert<?>> forJson(@Nullable String json) {
|
||||
return () -> new TestJsonContentAssert(json, null, null, null);
|
||||
}
|
||||
|
||||
private static class TestJsonContentAssert extends AbstractJsonContentAssert<TestJsonContentAssert> {
|
||||
|
||||
public TestJsonContentAssert(@Nullable String json, @Nullable GenericHttpMessageConverter<Object> jsonMessageConverter, @Nullable Class<?> resourceLoadClass, @Nullable Charset charset) {
|
||||
super(json, jsonMessageConverter, resourceLoadClass, charset, TestJsonContentAssert.class);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,479 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2024 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.test.json;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.assertj.core.api.AssertProvider;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.junit.jupiter.api.TestInstance.Lifecycle;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.skyscreamer.jsonassert.JSONCompareMode;
|
||||
import org.skyscreamer.jsonassert.comparator.DefaultComparator;
|
||||
import org.skyscreamer.jsonassert.comparator.JSONComparator;
|
||||
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.core.io.InputStreamResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
|
||||
/**
|
||||
* Tests for {@link JsonContentAssert}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@TestInstance(Lifecycle.PER_CLASS)
|
||||
class JsonContentAssertTests {
|
||||
|
||||
private static final String SOURCE = loadJson("source.json");
|
||||
|
||||
private static final String LENIENT_SAME = loadJson("lenient-same.json");
|
||||
|
||||
private static final String DIFFERENT = loadJson("different.json");
|
||||
|
||||
private static final JSONComparator COMPARATOR = new DefaultComparator(JSONCompareMode.LENIENT);
|
||||
|
||||
@Test
|
||||
void isEqualToWhenStringIsMatchingShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isEqualTo(SOURCE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEqualToWhenNullActualShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertThat(forJson(null)).isEqualTo(SOURCE));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEqualToWhenExpectedIsNotAStringShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isEqualTo(SOURCE.getBytes()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEqualToWhenExpectedIsNullShouldFail() {
|
||||
CharSequence actual = null;
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isEqualTo(actual, JSONCompareMode.LENIENT));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEqualToWhenStringIsMatchingAndLenientShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isEqualTo(LENIENT_SAME, JSONCompareMode.LENIENT);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEqualToWhenStringIsNotMatchingAndLenientShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isEqualTo(DIFFERENT, JSONCompareMode.LENIENT));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEqualToWhenResourcePathIsMatchingAndLenientShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isEqualTo("lenient-same.json", JSONCompareMode.LENIENT);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEqualToWhenResourcePathIsNotMatchingAndLenientShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isEqualTo("different.json", JSONCompareMode.LENIENT));
|
||||
}
|
||||
|
||||
Stream<Arguments> source() {
|
||||
return Stream.of(
|
||||
Arguments.of(new ClassPathResource("source.json", JsonContentAssertTests.class)),
|
||||
Arguments.of(new ByteArrayResource(SOURCE.getBytes())),
|
||||
Arguments.of(new FileSystemResource(createFile(SOURCE))),
|
||||
Arguments.of(new InputStreamResource(createInputStream(SOURCE))));
|
||||
}
|
||||
|
||||
Stream<Arguments> lenientSame() {
|
||||
return Stream.of(
|
||||
Arguments.of(new ClassPathResource("lenient-same.json", JsonContentAssertTests.class)),
|
||||
Arguments.of(new ByteArrayResource(LENIENT_SAME.getBytes())),
|
||||
Arguments.of(new FileSystemResource(createFile(LENIENT_SAME))),
|
||||
Arguments.of(new InputStreamResource(createInputStream(LENIENT_SAME))));
|
||||
}
|
||||
|
||||
Stream<Arguments> different() {
|
||||
return Stream.of(
|
||||
Arguments.of(new ClassPathResource("different.json", JsonContentAssertTests.class)),
|
||||
Arguments.of(new ByteArrayResource(DIFFERENT.getBytes())),
|
||||
Arguments.of(new FileSystemResource(createFile(DIFFERENT))),
|
||||
Arguments.of(new InputStreamResource(createInputStream(DIFFERENT))));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("lenientSame")
|
||||
void isEqualToWhenResourceIsMatchingAndLenientSameShouldPass(Resource expected) {
|
||||
assertThat(forJson(SOURCE)).isEqualTo(expected, JSONCompareMode.LENIENT);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("different")
|
||||
void isEqualToWhenResourceIsNotMatchingAndLenientShouldFail(Resource expected) {
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(
|
||||
() -> assertThat(forJson(SOURCE)).isEqualTo(expected, JSONCompareMode.LENIENT));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void isEqualToWhenStringIsMatchingAndComparatorShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isEqualTo(LENIENT_SAME, COMPARATOR);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEqualToWhenStringIsNotMatchingAndComparatorShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isEqualTo(DIFFERENT, COMPARATOR));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEqualToWhenResourcePathIsMatchingAndComparatorShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isEqualTo("lenient-same.json", COMPARATOR);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEqualToWhenResourcePathIsNotMatchingAndComparatorShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isEqualTo("different.json", COMPARATOR));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("lenientSame")
|
||||
void isEqualToWhenResourceIsMatchingAndComparatorShouldPass(Resource expected) {
|
||||
assertThat(forJson(SOURCE)).isEqualTo(expected, COMPARATOR);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("different")
|
||||
void isEqualToWhenResourceIsNotMatchingAndComparatorShouldFail(Resource expected) {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isEqualTo(expected, COMPARATOR));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isLenientlyEqualToWhenStringIsMatchingShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isLenientlyEqualTo(LENIENT_SAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isLenientlyEqualToWhenNullActualShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(null)).isLenientlyEqualTo(SOURCE));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isLenientlyEqualToWhenStringIsNotMatchingShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isLenientlyEqualTo(DIFFERENT));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isLenientlyEqualToWhenExpectedDoesNotExistShouldFail() {
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isLenientlyEqualTo("does-not-exist.json"))
|
||||
.withMessage("Unable to load JSON from class path resource [org/springframework/test/json/does-not-exist.json]");
|
||||
}
|
||||
|
||||
@Test
|
||||
void isLenientlyEqualToWhenResourcePathIsMatchingShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isLenientlyEqualTo("lenient-same.json");
|
||||
}
|
||||
|
||||
@Test
|
||||
void isLenientlyEqualToWhenResourcePathIsNotMatchingShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isLenientlyEqualTo("different.json"));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("lenientSame")
|
||||
void isLenientlyEqualToWhenResourceIsMatchingShouldPass(Resource expected) {
|
||||
assertThat(forJson(SOURCE)).isLenientlyEqualTo(expected);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("different")
|
||||
void isLenientlyEqualToWhenResourceIsNotMatchingShouldFail(Resource expected) {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isLenientlyEqualTo(expected));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isStrictlyEqualToWhenStringIsMatchingShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isStrictlyEqualTo(SOURCE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isStrictlyEqualToWhenStringIsNotMatchingShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isStrictlyEqualTo(LENIENT_SAME));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isStrictlyEqualToWhenResourcePathIsMatchingShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isStrictlyEqualTo("source.json");
|
||||
}
|
||||
|
||||
@Test
|
||||
void isStrictlyEqualToWhenResourcePathIsNotMatchingShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isStrictlyEqualTo("lenient-same.json"));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("source")
|
||||
void isStrictlyEqualToWhenResourceIsMatchingShouldPass(Resource expected) {
|
||||
assertThat(forJson(SOURCE)).isStrictlyEqualTo(expected);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("lenientSame")
|
||||
void isStrictlyEqualToWhenResourceIsNotMatchingShouldFail(Resource expected) {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isStrictlyEqualTo(expected));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void isNotEqualToWhenStringIsMatchingShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isNotEqualTo(SOURCE));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEqualToWhenNullActualShouldPass() {
|
||||
assertThat(forJson(null)).isNotEqualTo(SOURCE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEqualToWhenStringIsNotMatchingShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isNotEqualTo(DIFFERENT);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEqualToAsObjectWhenExpectedIsNotAStringShouldNotFail() {
|
||||
assertThat(forJson(SOURCE)).isNotEqualTo(SOURCE.getBytes());
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEqualToWhenStringIsMatchingAndLenientShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isNotEqualTo(LENIENT_SAME, JSONCompareMode.LENIENT));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEqualToWhenStringIsNotMatchingAndLenientShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isNotEqualTo(DIFFERENT, JSONCompareMode.LENIENT);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEqualToWhenResourcePathIsMatchingAndLenientShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(
|
||||
() -> assertThat(forJson(SOURCE)).isNotEqualTo("lenient-same.json", JSONCompareMode.LENIENT));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEqualToWhenResourcePathIsNotMatchingAndLenientShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isNotEqualTo("different.json", JSONCompareMode.LENIENT);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("lenientSame")
|
||||
void isNotEqualToWhenResourceIsMatchingAndLenientShouldFail(Resource expected) {
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> assertThat(forJson(SOURCE))
|
||||
.isNotEqualTo(expected, JSONCompareMode.LENIENT));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("different")
|
||||
void isNotEqualToWhenResourceIsNotMatchingAndLenientShouldPass(Resource expected) {
|
||||
assertThat(forJson(SOURCE)).isNotEqualTo(expected, JSONCompareMode.LENIENT);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEqualToWhenStringIsMatchingAndComparatorShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isNotEqualTo(LENIENT_SAME, COMPARATOR));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEqualToWhenStringIsNotMatchingAndComparatorShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isNotEqualTo(DIFFERENT, COMPARATOR);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEqualToWhenResourcePathIsMatchingAndComparatorShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isNotEqualTo("lenient-same.json", COMPARATOR));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEqualToWhenResourcePathIsNotMatchingAndComparatorShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isNotEqualTo("different.json", COMPARATOR);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("lenientSame")
|
||||
void isNotEqualToWhenResourceIsMatchingAndComparatorShouldFail(Resource expected) {
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(
|
||||
() -> assertThat(forJson(SOURCE)).isNotEqualTo(expected, COMPARATOR));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("different")
|
||||
void isNotEqualToWhenResourceIsNotMatchingAndComparatorShouldPass(Resource expected) {
|
||||
assertThat(forJson(SOURCE)).isNotEqualTo(expected, COMPARATOR);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEqualToWhenResourceIsMatchingAndComparatorShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isNotEqualTo(createResource(LENIENT_SAME), COMPARATOR));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEqualToWhenResourceIsNotMatchingAndComparatorShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isNotEqualTo(createResource(DIFFERENT), COMPARATOR);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotLenientlyEqualToWhenNullActualShouldPass() {
|
||||
assertThat(forJson(null)).isNotLenientlyEqualTo(SOURCE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotLenientlyEqualToWhenStringIsNotMatchingShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isNotLenientlyEqualTo(DIFFERENT);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotLenientlyEqualToWhenResourcePathIsMatchingShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isNotLenientlyEqualTo("lenient-same.json"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotLenientlyEqualToWhenResourcePathIsNotMatchingShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isNotLenientlyEqualTo("different.json");
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("lenientSame")
|
||||
void isNotLenientlyEqualToWhenResourceIsMatchingShouldFail(Resource expected) {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isNotLenientlyEqualTo(expected));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("different")
|
||||
void isNotLenientlyEqualToWhenResourceIsNotMatchingShouldPass(Resource expected) {
|
||||
assertThat(forJson(SOURCE)).isNotLenientlyEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotStrictlyEqualToWhenStringIsMatchingShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isNotStrictlyEqualTo(SOURCE));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotStrictlyEqualToWhenStringIsNotMatchingShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isNotStrictlyEqualTo(LENIENT_SAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotStrictlyEqualToWhenResourcePathIsMatchingShouldFail() {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isNotStrictlyEqualTo("source.json"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotStrictlyEqualToWhenResourcePathIsNotMatchingShouldPass() {
|
||||
assertThat(forJson(SOURCE)).isNotStrictlyEqualTo("lenient-same.json");
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("source")
|
||||
void isNotStrictlyEqualToWhenResourceIsMatchingShouldFail(Resource expected) {
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SOURCE)).isNotStrictlyEqualTo(expected));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("lenientSame")
|
||||
void isNotStrictlyEqualToWhenResourceIsNotMatchingShouldPass(Resource expected) {
|
||||
assertThat(forJson(SOURCE)).isNotStrictlyEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNullWhenActualIsNullShouldPass() {
|
||||
assertThat(forJson(null)).isNull();
|
||||
}
|
||||
|
||||
private Path createFile(String content) {
|
||||
try {
|
||||
Path temp = Files.createTempFile("file", ".json");
|
||||
Files.writeString(temp, content);
|
||||
return temp;
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private InputStream createInputStream(String content) {
|
||||
return new ByteArrayInputStream(content.getBytes());
|
||||
}
|
||||
|
||||
private Resource createResource(String content) {
|
||||
return new ByteArrayResource(content.getBytes());
|
||||
}
|
||||
|
||||
private static String loadJson(String path) {
|
||||
try {
|
||||
ClassPathResource resource = new ClassPathResource(path, JsonContentAssertTests.class);
|
||||
return new String(FileCopyUtils.copyToByteArray(resource.getInputStream()));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private AssertProvider<JsonContentAssert> forJson(@Nullable String json) {
|
||||
return () -> new JsonContentAssert(json, JsonContentAssertTests.class);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,323 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2024 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.test.json;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.assertj.core.api.AssertProvider;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.http.converter.GenericHttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
import static org.assertj.core.api.Assertions.entry;
|
||||
|
||||
/**
|
||||
* Tests for {@link JsonPathAssert}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class JsonPathAssertTests {
|
||||
|
||||
private static final String TYPES = loadJson("types.json");
|
||||
|
||||
private static final String SIMPSONS = loadJson("simpsons.json");
|
||||
|
||||
private static final String NULLS = loadJson("nulls.json");
|
||||
|
||||
private static final MappingJackson2HttpMessageConverter jsonHttpMessageConverter =
|
||||
new MappingJackson2HttpMessageConverter(new ObjectMapper());
|
||||
|
||||
|
||||
@Nested
|
||||
class HasPathTests {
|
||||
|
||||
@Test
|
||||
void hasPathForPresentAndNotNull() {
|
||||
assertThat(forJson(NULLS)).hasPath("$.valuename");
|
||||
}
|
||||
|
||||
@Test
|
||||
void hasPathForPresentAndNull() {
|
||||
assertThat(forJson(NULLS)).hasPath("$.nullname");
|
||||
}
|
||||
|
||||
@Test
|
||||
void hasPathForOperatorMatching() {
|
||||
assertThat(forJson(SIMPSONS)).
|
||||
hasPath("$.familyMembers[?(@.name == 'Homer')]");
|
||||
}
|
||||
|
||||
@Test
|
||||
void hasPathForOperatorNotMatching() {
|
||||
assertThat(forJson(SIMPSONS)).
|
||||
hasPath("$.familyMembers[?(@.name == 'Dilbert')]");
|
||||
}
|
||||
|
||||
@Test
|
||||
void hasPathForNotPresent() {
|
||||
String expression = "$.missing";
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(NULLS)).hasPath(expression))
|
||||
.satisfies(hasFailedToMatchPath("$.missing"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void hasPathSatisfying() {
|
||||
assertThat(forJson(TYPES)).hasPathSatisfying("$.str", value -> assertThat(value).isEqualTo("foo"))
|
||||
.hasPathSatisfying("$.num", value -> assertThat(value).isEqualTo(5));
|
||||
}
|
||||
|
||||
@Test
|
||||
void hasPathSatisfyingForPathNotPresent() {
|
||||
String expression = "missing";
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(NULLS)).hasPathSatisfying(expression, value -> {}))
|
||||
.satisfies(hasFailedToMatchPath(expression));
|
||||
}
|
||||
|
||||
@Test
|
||||
void doesNotHavePathForMissing() {
|
||||
assertThat(forJson(NULLS)).doesNotHavePath("$.missing");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void doesNotHavePathForPresent() {
|
||||
String expression = "$.valuename";
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(NULLS)).doesNotHavePath(expression))
|
||||
.satisfies(hasFailedToNotMatchPath(expression));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Nested
|
||||
class ExtractingPathTests {
|
||||
|
||||
@Test
|
||||
void isNullWithNullPathValue() {
|
||||
assertThat(forJson(NULLS)).extractingPath("$.nullname").isNull();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = { "$.str", "$.emptyString", "$.num", "$.bool", "$.arr",
|
||||
"$.emptyArray", "$.colorMap", "$.emptyMap" })
|
||||
void isNotNullWithValue(String path) {
|
||||
assertThat(forJson(TYPES)).extractingPath(path).isNotNull();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
void isEqualToOnRawValue(String path, Object expected) {
|
||||
assertThat(forJson(TYPES)).extractingPath(path).isEqualTo(expected);
|
||||
}
|
||||
|
||||
static Stream<Arguments> isEqualToOnRawValue() {
|
||||
return Stream.of(
|
||||
Arguments.of("$.str", "foo"),
|
||||
Arguments.of("$.num", 5),
|
||||
Arguments.of("$.bool", true),
|
||||
Arguments.of("$.arr", List.of(42)),
|
||||
Arguments.of("$.colorMap", Map.of("red", "rojo")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void asStringWithActualValue() {
|
||||
assertThat(forJson(TYPES)).extractingPath("@.str").asString().startsWith("f").endsWith("o");
|
||||
}
|
||||
|
||||
@Test
|
||||
void asStringIsEmpty() {
|
||||
assertThat(forJson(TYPES)).extractingPath("@.emptyString").asString().isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void asNumberWithActualValue() {
|
||||
assertThat(forJson(TYPES)).extractingPath("@.num").asNumber().isEqualTo(5);
|
||||
}
|
||||
|
||||
@Test
|
||||
void asBooleanWithActualValue() {
|
||||
assertThat(forJson(TYPES)).extractingPath("@.bool").asBoolean().isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void asArrayWithActualValue() {
|
||||
assertThat(forJson(TYPES)).extractingPath("@.arr").asArray().containsOnly(42);
|
||||
}
|
||||
|
||||
@Test
|
||||
void asArrayIsEmpty() {
|
||||
assertThat(forJson(TYPES)).extractingPath("@.emptyArray").asArray().isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void asArrayWithFilterPredicatesMatching() {
|
||||
assertThat(forJson(SIMPSONS))
|
||||
.extractingPath("$.familyMembers[?(@.name == 'Bart')]").asArray().hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void asArrayWithFilterPredicatesNotMatching() {
|
||||
assertThat(forJson(SIMPSONS)).
|
||||
extractingPath("$.familyMembers[?(@.name == 'Dilbert')]").asArray().isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void asMapWithActualValue() {
|
||||
assertThat(forJson(TYPES)).extractingPath("@.colorMap").asMap().containsOnly(entry("red", "rojo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void asMapIsEmpty() {
|
||||
assertThat(forJson(TYPES)).extractingPath("@.emptyMap").asMap().isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void convertToWithoutHttpMessageConverterShouldFail() {
|
||||
JsonPathValueAssert path = assertThat(forJson(SIMPSONS)).extractingPath("$.familyMembers[0]");
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> path.convertTo(Member.class))
|
||||
.withMessage("No JSON message converter available to convert {name=Homer}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void convertToTargetType() {
|
||||
assertThat(forJson(SIMPSONS, jsonHttpMessageConverter))
|
||||
.extractingPath("$.familyMembers[0]").convertTo(Member.class)
|
||||
.satisfies(member -> assertThat(member.name).isEqualTo("Homer"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void convertToIncompatibleTargetTypeShouldFail() {
|
||||
JsonPathValueAssert path = assertThat(forJson(SIMPSONS, jsonHttpMessageConverter))
|
||||
.extractingPath("$.familyMembers[0]");
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> path.convertTo(Customer.class))
|
||||
.withMessageContainingAll("Expected value at JSON path \"$.familyMembers[0]\":",
|
||||
Customer.class.getName(), "name");
|
||||
}
|
||||
|
||||
@Test
|
||||
void convertArrayToParameterizedType() {
|
||||
assertThat(forJson(SIMPSONS, jsonHttpMessageConverter))
|
||||
.extractingPath("$.familyMembers")
|
||||
.convertTo(new ParameterizedTypeReference<List<Member>>() {})
|
||||
.satisfies(family -> assertThat(family).hasSize(5).element(0).isEqualTo(new Member("Homer")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEmptyWithPathHavingNullValue() {
|
||||
assertThat(forJson(NULLS)).extractingPath("nullname").isEmpty();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = { "$.emptyString", "$.emptyArray", "$.emptyMap" })
|
||||
void isEmptyWithEmptyValue(String path) {
|
||||
assertThat(forJson(TYPES)).extractingPath(path).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEmptyForPathWithFilterMatching() {
|
||||
String expression = "$.familyMembers[?(@.name == 'Bart')]";
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SIMPSONS)).extractingPath(expression).isEmpty())
|
||||
.withMessageContainingAll("Expected value at JSON path \"" + expression + "\"",
|
||||
"[{\"name\":\"Bart\"}]", "To be empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEmptyForPathWithFilterNotMatching() {
|
||||
assertThat(forJson(SIMPSONS)).extractingPath("$.familyMembers[?(@.name == 'Dilbert')]").isEmpty();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = { "$.str", "$.num", "$.bool", "$.arr", "$.colorMap" })
|
||||
void isNotEmptyWithNonNullValue(String path) {
|
||||
assertThat(forJson(TYPES)).extractingPath(path).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEmptyForPathWithFilterMatching() {
|
||||
assertThat(forJson(SIMPSONS)).extractingPath("$.familyMembers[?(@.name == 'Bart')]").isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEmptyForPathWithFilterNotMatching() {
|
||||
String expression = "$.familyMembers[?(@.name == 'Dilbert')]";
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertThat(forJson(SIMPSONS)).extractingPath(expression).isNotEmpty())
|
||||
.withMessageContainingAll("Expected value at JSON path \"" + expression + "\"",
|
||||
"To not be empty");
|
||||
}
|
||||
|
||||
|
||||
private record Member(String name) {}
|
||||
|
||||
private record Customer(long id, String username) {}
|
||||
|
||||
}
|
||||
|
||||
private Consumer<AssertionError> hasFailedToMatchPath(String expression) {
|
||||
return error -> assertThat(error.getMessage()).containsSubsequence("Expecting:",
|
||||
"To match JSON path:", "\"" + expression + "\"");
|
||||
}
|
||||
|
||||
private Consumer<AssertionError> hasFailedToNotMatchPath(String expression) {
|
||||
return error -> assertThat(error.getMessage()).containsSubsequence("Expecting:",
|
||||
"Not to match JSON path:", "\"" + expression + "\"");
|
||||
}
|
||||
|
||||
|
||||
private static String loadJson(String path) {
|
||||
try {
|
||||
ClassPathResource resource = new ClassPathResource(path, JsonPathAssertTests.class);
|
||||
return new String(FileCopyUtils.copyToByteArray(resource.getInputStream()));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private AssertProvider<JsonPathAssert> forJson(String json) {
|
||||
return forJson(json, null);
|
||||
}
|
||||
|
||||
private AssertProvider<JsonPathAssert> forJson(String json,
|
||||
@Nullable GenericHttpMessageConverter<Object> jsonHttpMessageConverter) {
|
||||
return () -> new JsonPathAssert(json, jsonHttpMessageConverter);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -31,7 +31,7 @@ import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
import org.springframework.mock.web.MockServletContext;
|
||||
import org.springframework.test.json.JsonPathAssert;
|
||||
import org.springframework.test.json.AbstractJsonContentAssert;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
@@ -99,9 +99,9 @@ class AssertableMockMvcTests {
|
||||
@Test
|
||||
void createWithControllersHasNoHttpMessageConverter() {
|
||||
AssertableMockMvc mockMvc = AssertableMockMvc.of(new HelloController());
|
||||
JsonPathAssert jsonPathAssert = assertThat(mockMvc.perform(get("/json"))).hasStatusOk().body().jsonPath();
|
||||
AbstractJsonContentAssert<?> jsonContentAssert = assertThat(mockMvc.perform(get("/json"))).hasStatusOk().body().jsonPath();
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> jsonPathAssert.extractingPath("$").convertTo(Message.class))
|
||||
.isThrownBy(() -> jsonContentAssert.extractingPath("$").convertTo(Message.class))
|
||||
.withMessageContaining("No JSON message converter available");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user