Skip to content

Commit aa4b226

Browse files
committed
Add support for converting json values using AssertFactory
This commit benefits from a feature introduced in AssertJ 3.26.0, see assertj/assertj#3377. This allows to use any AssertFactory and convert the actual value to the type the factory manages. Previously, we were using ParameterizedTypeReference to express the type with its generic signature but the returned assert object would not be narrowed to the converted type. Thanks to this change, we can request to convert the actual value to `InstanceOfAssertFactories.list(Member.class)` and get a `ListAssert` of `Member` as a result, rather than an `ObjectAssert` of `List<User>`. Thanks very much to @scordio for his efforts. Closes gh-32953
1 parent 6212831 commit aa4b226

File tree

3 files changed

+23
-16
lines changed

3 files changed

+23
-16
lines changed

spring-test/src/main/java/org/springframework/test/json/AbstractJsonValueAssert.java

+18-9
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,18 @@
2020
import java.util.List;
2121
import java.util.Map;
2222

23+
import org.assertj.core.api.AbstractAssert;
2324
import org.assertj.core.api.AbstractBooleanAssert;
2425
import org.assertj.core.api.AbstractMapAssert;
2526
import org.assertj.core.api.AbstractObjectAssert;
2627
import org.assertj.core.api.AbstractStringAssert;
28+
import org.assertj.core.api.AssertFactory;
2729
import org.assertj.core.api.Assertions;
30+
import org.assertj.core.api.InstanceOfAssertFactories;
2831
import org.assertj.core.api.ObjectArrayAssert;
2932
import org.assertj.core.error.BasicErrorMessageFactory;
3033
import org.assertj.core.internal.Failures;
3134

32-
import org.springframework.core.ParameterizedTypeReference;
3335
import org.springframework.core.ResolvableType;
3436
import org.springframework.http.HttpInputMessage;
3537
import org.springframework.http.MediaType;
@@ -152,16 +154,23 @@ public <T> AbstractObjectAssert<?, T> convertTo(Class<T> target) {
152154
}
153155

154156
/**
155-
* Verify that the actual value can be converted to an instance of the
156-
* given {@code target}, and produce a new {@linkplain AbstractObjectAssert
157-
* assertion} object narrowed to that type.
158-
* @param target the {@linkplain ParameterizedTypeReference parameterized
159-
* type} to convert the actual value to
157+
* Verify that the actual value can be converted to an instance of the type
158+
* defined by the given {@link AssertFactory} and return a new Assert narrowed
159+
* to that type.
160+
* <p>{@link InstanceOfAssertFactories} provides static factories for all the
161+
* types supported by {@link Assertions#assertThat}. Additional factories can
162+
* be created by implementing {@link AssertFactory}.
163+
* <p>Example: <pre><code class="java">
164+
* // Check that the json value is an array of 3 users
165+
* assertThat(jsonValue).convertTo(InstanceOfAssertFactories.list(User.class))
166+
* hasSize(3); // ListAssert of User
167+
* </code></pre>
168+
* @param assertFactory the {@link AssertFactory} to use to produce a narrowed
169+
* Assert for the type that it defines.
160170
*/
161-
public <T> AbstractObjectAssert<?, T> convertTo(ParameterizedTypeReference<T> target) {
171+
public <ASSERT extends AbstractAssert<?, ?>> ASSERT convertTo(AssertFactory<?, ASSERT> assertFactory) {
162172
isNotNull();
163-
T value = convertToTargetType(target.getType());
164-
return Assertions.assertThat(value);
173+
return assertFactory.createAssert(this::convertToTargetType);
165174
}
166175

167176
/**

spring-test/src/test/java/org/springframework/test/json/AbstractJsonContentAssertTests.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
import com.fasterxml.jackson.databind.ObjectMapper;
3030
import org.assertj.core.api.AssertProvider;
31+
import org.assertj.core.api.InstanceOfAssertFactories;
3132
import org.json.JSONException;
3233
import org.json.JSONObject;
3334
import org.junit.jupiter.api.Nested;
@@ -42,7 +43,6 @@
4243
import org.skyscreamer.jsonassert.JSONCompareResult;
4344
import org.skyscreamer.jsonassert.comparator.JSONComparator;
4445

45-
import org.springframework.core.ParameterizedTypeReference;
4646
import org.springframework.core.io.ByteArrayResource;
4747
import org.springframework.core.io.ClassPathResource;
4848
import org.springframework.core.io.FileSystemResource;
@@ -286,8 +286,8 @@ void convertToIncompatibleTargetTypeShouldFail() {
286286
void convertArrayToParameterizedType() {
287287
assertThat(forJson(SIMPSONS, jsonHttpMessageConverter))
288288
.extractingPath("$.familyMembers")
289-
.convertTo(new ParameterizedTypeReference<List<Member>>() {})
290-
.satisfies(family -> assertThat(family).hasSize(5).element(0).isEqualTo(new Member("Homer")));
289+
.convertTo(InstanceOfAssertFactories.list(Member.class))
290+
.hasSize(5).element(0).isEqualTo(new Member("Homer"));
291291
}
292292

293293
@Test

spring-test/src/test/java/org/springframework/test/json/JsonPathValueAssertTests.java

+2-4
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import org.junit.jupiter.api.Nested;
2929
import org.junit.jupiter.api.Test;
3030

31-
import org.springframework.core.ParameterizedTypeReference;
3231
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
3332
import org.springframework.lang.Nullable;
3433
import org.springframework.util.StringUtils;
@@ -231,9 +230,8 @@ void convertArrayToListOfPojo() {
231230
Map<?, ?> user2 = Map.of("id", 5678, "name", "Sarah", "active", false);
232231
Map<?, ?> user3 = Map.of("id", 9012, "name", "Sophia", "active", true);
233232
assertThat(forValue(List.of(user1, user2, user3)))
234-
.convertTo(new ParameterizedTypeReference<List<User>>() {})
235-
.satisfies(users -> assertThat(users).hasSize(3).extracting("name")
236-
.containsExactly("John", "Sarah", "Sophia"));
233+
.convertTo(InstanceOfAssertFactories.list(User.class))
234+
.hasSize(3).extracting("name").containsExactly("John", "Sarah", "Sophia");
237235
}
238236

239237
@Test

0 commit comments

Comments
 (0)