Merge branch '4.0.x' into 4.1.x

Closes gh-51418
This commit is contained in:
Stéphane Nicoll
2026-08-24 08:26:06 +02:00
3 changed files with 47 additions and 13 deletions
@@ -17,7 +17,6 @@
package org.springframework.boot.test.json;
import java.io.BufferedReader;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@@ -298,7 +297,6 @@ public abstract class AbstractJsonMarshalTester<T> {
Assert.notNull(resource, "'resource' must not be null");
InputStream inputStream = resource.getInputStream();
T object = readObject(inputStream, getTypeNotNull());
closeQuietly(inputStream);
return new ObjectContent<>(this.type, object);
}
@@ -323,19 +321,9 @@ public abstract class AbstractJsonMarshalTester<T> {
verify();
Assert.notNull(reader, "'reader' must not be null");
T object = readObject(reader, getTypeNotNull());
closeQuietly(reader);
return new ObjectContent<>(this.type, object);
}
private void closeQuietly(Closeable closeable) {
try {
closeable.close();
}
catch (IOException ex) {
// Ignore
}
}
private void verify() {
Assert.state(this.resourceLoadClass != null, "Uninitialized JsonMarshalTester (ResourceLoadClass is null)");
Assert.state(this.type != null, "Uninitialized JsonMarshalTester (Type is null)");
@@ -86,7 +86,9 @@ public class GsonTester<T> extends AbstractJsonMarshalTester<T> {
@Override
protected T readObject(Reader reader, ResolvableType type) throws IOException {
return this.gson.fromJson(reader, type.getType());
try (reader) {
return this.gson.fromJson(reader, type.getType());
}
}
/**
@@ -18,6 +18,7 @@ package org.springframework.boot.test.json;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
@@ -40,7 +41,12 @@ import org.springframework.util.FileCopyUtils;
import org.springframework.util.ReflectionUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatException;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.then;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
/**
* Tests for {@link AbstractJsonMarshalTester}.
@@ -55,6 +61,8 @@ abstract class AbstractJsonMarshalTesterTests {
private static final String ARRAY_JSON = "[" + JSON + "]";
private static final String TRUNCATED_JSON = "{\"name\":\"Spring\",";
private static final ExampleObject OBJECT = createExampleObject("Spring", 123);
private static final ResolvableType TYPE = ResolvableType.forClass(ExampleObject.class);
@@ -145,6 +153,26 @@ abstract class AbstractJsonMarshalTesterTests {
assertThat(tester.read(resource)).isEqualTo(OBJECT);
}
@Test
void readResourceShouldCloseInputStream() throws IOException {
Resource resource = mock();
InputStream stream = spy(new ByteArrayInputStream(JSON.getBytes()));
given(resource.getInputStream()).willReturn(stream);
AbstractJsonMarshalTester<Object> tester = createTester(TYPE);
assertThat(tester.read(stream)).isEqualTo(OBJECT);
then(stream).should().close();
}
@Test
void readResourceWhenReadFailsShouldCloseInputStream() throws IOException {
Resource resource = mock();
InputStream stream = spy(new ByteArrayInputStream(TRUNCATED_JSON.getBytes()));
given(resource.getInputStream()).willReturn(stream);
AbstractJsonMarshalTester<Object> tester = createTester(TYPE);
assertThatException().isThrownBy(() -> tester.read(resource));
then(stream).should().close();
}
@Test
void readReaderShouldReturnObject() throws Exception {
Reader reader = new StringReader(JSON);
@@ -152,6 +180,22 @@ abstract class AbstractJsonMarshalTesterTests {
assertThat(tester.read(reader)).isEqualTo(OBJECT);
}
@Test
void readReaderShouldCloseReader() throws IOException {
Reader reader = spy(new StringReader(JSON));
AbstractJsonMarshalTester<Object> tester = createTester(TYPE);
assertThat(tester.read(reader)).isEqualTo(OBJECT);
then(reader).should().close();
}
@Test
void readReaderWhenReadFailsShouldCloseReader() throws IOException {
Reader reader = spy(new StringReader(TRUNCATED_JSON));
AbstractJsonMarshalTester<Object> tester = createTester(TYPE);
assertThatException().isThrownBy(() -> tester.read(reader));
then(reader).should().close();
}
@Test
void parseListShouldReturnContent() throws Exception {
ResolvableType type = ResolvableTypes.get("listOfExampleObject");