diff --git a/core/spring-boot-test/src/main/java/org/springframework/boot/test/json/AbstractJsonMarshalTester.java b/core/spring-boot-test/src/main/java/org/springframework/boot/test/json/AbstractJsonMarshalTester.java index a16660e994f5..1456442b7ad6 100644 --- a/core/spring-boot-test/src/main/java/org/springframework/boot/test/json/AbstractJsonMarshalTester.java +++ b/core/spring-boot-test/src/main/java/org/springframework/boot/test/json/AbstractJsonMarshalTester.java @@ -297,9 +297,13 @@ public ObjectContent read(Resource resource) throws IOException { verify(); 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); + try { + T object = readObject(inputStream, getTypeNotNull()); + return new ObjectContent<>(this.type, object); + } + finally { + closeQuietly(inputStream); + } } /** @@ -322,9 +326,13 @@ public T readObject(Reader reader) throws IOException { public ObjectContent read(Reader reader) throws IOException { verify(); Assert.notNull(reader, "'reader' must not be null"); - T object = readObject(reader, getTypeNotNull()); - closeQuietly(reader); - return new ObjectContent<>(this.type, object); + try { + T object = readObject(reader, getTypeNotNull()); + return new ObjectContent<>(this.type, object); + } + finally { + closeQuietly(reader); + } } private void closeQuietly(Closeable closeable) { diff --git a/core/spring-boot-test/src/test/java/org/springframework/boot/test/json/AbstractJsonMarshalTesterTests.java b/core/spring-boot-test/src/test/java/org/springframework/boot/test/json/AbstractJsonMarshalTesterTests.java index 490b2d13d2db..092b5130c588 100644 --- a/core/spring-boot-test/src/test/java/org/springframework/boot/test/json/AbstractJsonMarshalTesterTests.java +++ b/core/spring-boot-test/src/test/java/org/springframework/boot/test/json/AbstractJsonMarshalTesterTests.java @@ -18,6 +18,7 @@ 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,13 @@ 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.atLeastOnce; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; /** * Tests for {@link AbstractJsonMarshalTester}. @@ -55,6 +62,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 +154,16 @@ void readResourceShouldReturnObject() throws Exception { assertThat(tester.read(resource)).isEqualTo(OBJECT); } + @Test + void readResourceWhenReadFailsShouldCloseInputStream() throws IOException { + Resource resource = mock(); + InputStream inputStream = spy(new ByteArrayInputStream(TRUNCATED_JSON.getBytes())); + given(resource.getInputStream()).willReturn(inputStream); + AbstractJsonMarshalTester tester = createTester(TYPE); + assertThatException().isThrownBy(() -> tester.read(resource)); + then(inputStream).should(atLeastOnce()).close(); + } + @Test void readReaderShouldReturnObject() throws Exception { Reader reader = new StringReader(JSON); @@ -152,6 +171,14 @@ void readReaderShouldReturnObject() throws Exception { assertThat(tester.read(reader)).isEqualTo(OBJECT); } + @Test + void readReaderWhenReadFailsShouldCloseReader() throws IOException { + Reader reader = spy(new StringReader(TRUNCATED_JSON)); + AbstractJsonMarshalTester tester = createTester(TYPE); + assertThatException().isThrownBy(() -> tester.read(reader)); + then(reader).should(atLeastOnce()).close(); + } + @Test void parseListShouldReturnContent() throws Exception { ResolvableType type = ResolvableTypes.get("listOfExampleObject");