1 /*
2  * Copyright (C) 2007 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.common.io;
18 
19 import static org.mockito.Mockito.doThrow;
20 import static org.mockito.Mockito.mock;
21 import static org.mockito.Mockito.verify;
22 
23 import java.io.ByteArrayInputStream;
24 import java.io.Closeable;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.io.Reader;
28 import junit.framework.TestCase;
29 
30 /**
31  * Unit tests for {@link Closeables}.
32  *
33  * <p>Checks proper closing behavior, and ensures that IOExceptions on Closeable.close() are not
34  * propagated out from the {@link Closeables#close} method if {@code swallowException} is true.
35  *
36  * @author Michael Lancaster
37  */
38 public class CloseablesTest extends TestCase {
39   private Closeable mockCloseable;
40 
testClose_closeableClean()41   public void testClose_closeableClean() throws IOException {
42     // make sure that no exception is thrown regardless of value of
43     // 'swallowException' when the mock does not throw an exception.
44     setupCloseable(false);
45     doClose(mockCloseable, false, false);
46 
47     setupCloseable(false);
48     doClose(mockCloseable, true, false);
49   }
50 
testClose_closeableWithEatenException()51   public void testClose_closeableWithEatenException() throws IOException {
52     // make sure that no exception is thrown if 'swallowException' is true
53     // when the mock does throw an exception.
54     setupCloseable(true);
55     doClose(mockCloseable, true);
56   }
57 
testClose_closeableWithThrownException()58   public void testClose_closeableWithThrownException() throws IOException {
59     // make sure that the exception is thrown if 'swallowException' is false
60     // when the mock does throw an exception.
61     setupCloseable(true);
62     doClose(mockCloseable, false);
63   }
64 
testCloseQuietly_inputStreamWithEatenException()65   public void testCloseQuietly_inputStreamWithEatenException() throws IOException {
66     TestInputStream in =
67         new TestInputStream(new ByteArrayInputStream(new byte[1]), TestOption.CLOSE_THROWS);
68     Closeables.closeQuietly(in);
69     assertTrue(in.closed());
70   }
71 
testCloseQuietly_readerWithEatenException()72   public void testCloseQuietly_readerWithEatenException() throws IOException {
73     TestReader in = new TestReader(TestOption.CLOSE_THROWS);
74     Closeables.closeQuietly(in);
75     assertTrue(in.closed());
76   }
77 
testCloseNull()78   public void testCloseNull() throws IOException {
79     Closeables.close(null, true);
80     Closeables.close(null, false);
81   }
82 
testCloseQuietlyNull_inputStream()83   public void testCloseQuietlyNull_inputStream() {
84     Closeables.closeQuietly((InputStream) null);
85   }
86 
testCloseQuietlyNull_reader()87   public void testCloseQuietlyNull_reader() {
88     Closeables.closeQuietly((Reader) null);
89   }
90 
91   // Set up a closeable to expect to be closed, and optionally to throw an
92   // exception.
setupCloseable(boolean shouldThrow)93   private void setupCloseable(boolean shouldThrow) throws IOException {
94     mockCloseable = mock(Closeable.class);
95     if (shouldThrow) {
96       doThrow(new IOException("This should only appear in the logs. It should not be rethrown."))
97           .when(mockCloseable)
98           .close();
99     }
100   }
101 
doClose(Closeable closeable, boolean swallowException)102   private void doClose(Closeable closeable, boolean swallowException) throws IOException {
103     doClose(closeable, swallowException, !swallowException);
104   }
105 
106   // Close the closeable using the Closeables, passing in the swallowException
107   // parameter. expectThrown determines whether we expect an exception to
108   // be thrown by Closeables.close;
doClose(Closeable closeable, boolean swallowException, boolean expectThrown)109   private void doClose(Closeable closeable, boolean swallowException, boolean expectThrown)
110       throws IOException {
111     try {
112       Closeables.close(closeable, swallowException);
113       if (expectThrown) {
114         fail("Didn't throw exception.");
115       }
116     } catch (IOException e) {
117       if (!expectThrown) {
118         fail("Threw exception");
119       }
120     }
121     verify(closeable).close();
122   }
123 }
124