View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.dbcp2;
19  
20  import static org.junit.jupiter.api.Assertions.assertEquals;
21  import static org.junit.jupiter.api.Assertions.assertFalse;
22  import static org.junit.jupiter.api.Assertions.assertInstanceOf;
23  import static org.junit.jupiter.api.Assertions.assertNull;
24  import static org.junit.jupiter.api.Assertions.assertThrows;
25  import static org.junit.jupiter.api.Assertions.assertTrue;
26  import static org.mockito.Mockito.mock;
27  import static org.mockito.Mockito.times;
28  import static org.mockito.Mockito.verify;
29  
30  import java.lang.reflect.Proxy;
31  import java.sql.Connection;
32  import java.sql.SQLException;
33  import java.sql.Statement;
34  
35  import org.junit.jupiter.api.AfterEach;
36  import org.junit.jupiter.api.BeforeEach;
37  import org.junit.jupiter.api.Test;
38  
39  public class TestDelegatingStatement {
40  
41      private static final class TesterStatementNonWrapping extends TesterStatement {
42  
43          public TesterStatementNonWrapping(final Connection conn) {
44              super(conn);
45          }
46  
47          @Override
48          public boolean isWrapperFor(final Class<?> iface) throws SQLException {
49              return false;
50          }
51      }
52  
53      private DelegatingConnection<Connection> delegatingConnection;
54      private TesterConnection testerConnection;
55      private Statement mockedStatement;
56      private DelegatingStatement delegatingStatement;
57      private DelegatingStatement delegatingTesterStatement;
58      private TesterResultSet testerResultSet;
59      private TesterStatement testerStatement;
60  
61      @AfterEach
62      public void afterEach() {
63          testerResultSet.setSqlExceptionOnClose(false);
64          testerStatement.setSqlExceptionOnClose(false);
65      }
66  
67      @BeforeEach
68      public void setUp() throws Exception {
69          testerConnection = new TesterConnection("test", "test");
70          delegatingConnection = new DelegatingConnection<>(testerConnection);
71          mockedStatement = mock(Statement.class);
72          testerStatement = new TesterStatement(testerConnection);
73          delegatingStatement = new DelegatingStatement(delegatingConnection, mockedStatement);
74          delegatingTesterStatement = new DelegatingStatement(delegatingConnection, testerStatement);
75          testerResultSet = new TesterResultSet(mockedStatement);
76      }
77  
78      @Test
79      void testAddBatchString() throws Exception {
80          try {
81              delegatingStatement.addBatch("foo");
82          } catch (final SQLException e) {
83          }
84          verify(mockedStatement, times(1)).addBatch("foo");
85      }
86  
87      @Test
88      void testCancel() throws Exception {
89          try {
90              delegatingStatement.cancel();
91          } catch (final SQLException e) {
92          }
93          verify(mockedStatement, times(1)).cancel();
94      }
95  
96      @Test
97      void testCheckOpen() throws Exception {
98          delegatingStatement.checkOpen();
99          delegatingStatement.close();
100         assertThrows(SQLException.class, delegatingStatement::checkOpen);
101     }
102 
103     @Test
104     void testClearBatch() throws Exception {
105         try {
106             delegatingStatement.clearBatch();
107         } catch (final SQLException e) {
108         }
109         verify(mockedStatement, times(1)).clearBatch();
110     }
111 
112     @Test
113     void testClearWarnings() throws Exception {
114         try {
115             delegatingStatement.clearWarnings();
116         } catch (final SQLException e) {
117         }
118         verify(mockedStatement, times(1)).clearWarnings();
119     }
120 
121     @Test
122     void testClose() throws Exception {
123         try {
124             delegatingStatement.close();
125         } catch (final SQLException e) {
126         }
127         verify(mockedStatement, times(1)).close();
128     }
129 
130     @Test
131     void testCloseOnCompletion() throws Exception {
132         try {
133             delegatingStatement.closeOnCompletion();
134         } catch (final SQLException e) {
135         }
136         verify(mockedStatement, times(1)).closeOnCompletion();
137     }
138 
139     @Test
140     void testCloseWithResultSetCloseException() throws Exception {
141         testerResultSet.setSqlExceptionOnClose(true);
142         delegatingStatement.addTrace(testerResultSet);
143         final SQLException e = assertThrows(SQLException.class, delegatingStatement::close);
144         assertInstanceOf(SQLExceptionList.class, e);
145         verify(mockedStatement, times(1)).close();
146     }
147 
148     @Test
149     void testCloseWithStatementCloseException() throws Exception {
150         testerStatement.setSqlExceptionOnClose(true);
151         final SQLException e = assertThrows(SQLException.class, delegatingTesterStatement::close);
152         assertInstanceOf(SQLExceptionList.class, e);
153     }
154 
155     @Test
156     void testExecuteBatch() throws Exception {
157         try {
158             delegatingStatement.executeBatch();
159         } catch (final SQLException e) {
160         }
161         verify(mockedStatement, times(1)).executeBatch();
162     }
163 
164     @Test
165     void testExecuteLargeBatch() throws Exception {
166         try {
167             delegatingStatement.executeLargeBatch();
168         } catch (final SQLException e) {
169         }
170         verify(mockedStatement, times(1)).executeLargeBatch();
171     }
172 
173     @Test
174     void testExecuteLargeUpdateString() throws Exception {
175         try {
176             delegatingStatement.executeLargeUpdate("foo");
177         } catch (final SQLException e) {
178         }
179         verify(mockedStatement, times(1)).executeLargeUpdate("foo");
180     }
181 
182     @Test
183     void testExecuteLargeUpdateStringInteger() throws Exception {
184         try {
185             delegatingStatement.executeLargeUpdate("foo", 1);
186         } catch (final SQLException e) {
187         }
188         verify(mockedStatement, times(1)).executeLargeUpdate("foo", 1);
189     }
190 
191     @Test
192     void testExecuteLargeUpdateStringIntegerArray() throws Exception {
193         try {
194             delegatingStatement.executeLargeUpdate("foo", (int[]) null);
195         } catch (final SQLException e) {
196         }
197         verify(mockedStatement, times(1)).executeLargeUpdate("foo", (int[]) null);
198     }
199 
200     @Test
201     void testExecuteLargeUpdateStringStringArray() throws Exception {
202         try {
203             delegatingStatement.executeLargeUpdate("foo", (String[]) null);
204         } catch (final SQLException e) {
205         }
206         verify(mockedStatement, times(1)).executeLargeUpdate("foo", (String[]) null);
207     }
208 
209     @Test
210     void testExecuteQueryReturnsNull() throws Exception {
211         assertNull(delegatingStatement.executeQuery("null"));
212     }
213 
214     @Test
215     void testExecuteQueryString() throws Exception {
216         try {
217             delegatingStatement.executeQuery("foo");
218         } catch (final SQLException e) {
219         }
220         verify(mockedStatement, times(1)).executeQuery("foo");
221     }
222 
223     @Test
224     void testExecuteString() throws Exception {
225         try {
226             delegatingStatement.execute("foo");
227         } catch (final SQLException e) {
228         }
229         verify(mockedStatement, times(1)).execute("foo");
230     }
231 
232     @Test
233     void testExecuteStringInteger() throws Exception {
234         try {
235             delegatingStatement.execute("foo", 1);
236         } catch (final SQLException e) {
237         }
238         verify(mockedStatement, times(1)).execute("foo", 1);
239     }
240 
241     @Test
242     void testExecuteStringIntegerArray() throws Exception {
243         try {
244             delegatingStatement.execute("foo", (int[]) null);
245         } catch (final SQLException e) {
246         }
247         verify(mockedStatement, times(1)).execute("foo", (int[]) null);
248     }
249 
250     @Test
251     void testExecuteStringStringArray() throws Exception {
252         try {
253             delegatingStatement.execute("foo", (String[]) null);
254         } catch (final SQLException e) {
255         }
256         verify(mockedStatement, times(1)).execute("foo", (String[]) null);
257     }
258 
259     @Test
260     void testExecuteUpdateString() throws Exception {
261         try {
262             delegatingStatement.executeUpdate("foo");
263         } catch (final SQLException e) {
264         }
265         verify(mockedStatement, times(1)).executeUpdate("foo");
266     }
267 
268     @Test
269     void testExecuteUpdateStringInteger() throws Exception {
270         try {
271             delegatingStatement.executeUpdate("foo", 1);
272         } catch (final SQLException e) {
273         }
274         verify(mockedStatement, times(1)).executeUpdate("foo", 1);
275     }
276 
277     @Test
278     void testExecuteUpdateStringIntegerArray() throws Exception {
279         try {
280             delegatingStatement.executeUpdate("foo", (int[]) null);
281         } catch (final SQLException e) {
282         }
283         verify(mockedStatement, times(1)).executeUpdate("foo", (int[]) null);
284     }
285 
286     @Test
287     void testExecuteUpdateStringStringArray() throws Exception {
288         try {
289             delegatingStatement.executeUpdate("foo", (String[]) null);
290         } catch (final SQLException e) {
291         }
292         verify(mockedStatement, times(1)).executeUpdate("foo", (String[]) null);
293     }
294 
295     /**
296      * This method is a bit special, and return the delegate connection, not the wrapped statement's connection.
297      *
298      * @throws Exception
299      */
300     @Test
301     void testGetConnection() throws Exception {
302         try {
303             delegatingStatement.getConnection();
304         } catch (final SQLException e) {
305         }
306         verify(mockedStatement, times(0)).getConnection();
307     }
308 
309     @Test
310     void testGetDelegate() throws Exception {
311         assertEquals(mockedStatement, delegatingStatement.getDelegate());
312     }
313 
314     @Test
315     void testGetFetchDirection() throws Exception {
316         try {
317             delegatingStatement.getFetchDirection();
318         } catch (final SQLException e) {
319         }
320         verify(mockedStatement, times(1)).getFetchDirection();
321     }
322 
323     @Test
324     void testGetFetchSize() throws Exception {
325         try {
326             delegatingStatement.getFetchSize();
327         } catch (final SQLException e) {
328         }
329         verify(mockedStatement, times(1)).getFetchSize();
330     }
331 
332     @Test
333     void testGetGeneratedKeys() throws Exception {
334         try {
335             delegatingStatement.getGeneratedKeys();
336         } catch (final SQLException e) {
337         }
338         verify(mockedStatement, times(1)).getGeneratedKeys();
339     }
340 
341     @Test
342     void testGetLargeMaxRows() throws Exception {
343         try {
344             delegatingStatement.getLargeMaxRows();
345         } catch (final SQLException e) {
346         }
347         verify(mockedStatement, times(1)).getLargeMaxRows();
348     }
349 
350     @Test
351     void testGetLargeUpdateCount() throws Exception {
352         try {
353             delegatingStatement.getLargeUpdateCount();
354         } catch (final SQLException e) {
355         }
356         verify(mockedStatement, times(1)).getLargeUpdateCount();
357     }
358 
359     @Test
360     void testGetMaxFieldSize() throws Exception {
361         try {
362             delegatingStatement.getMaxFieldSize();
363         } catch (final SQLException e) {
364         }
365         verify(mockedStatement, times(1)).getMaxFieldSize();
366     }
367 
368     @Test
369     void testGetMaxRows() throws Exception {
370         try {
371             delegatingStatement.getMaxRows();
372         } catch (final SQLException e) {
373         }
374         verify(mockedStatement, times(1)).getMaxRows();
375     }
376 
377     @Test
378     void testGetMoreResults() throws Exception {
379         try {
380             delegatingStatement.getMoreResults();
381         } catch (final SQLException e) {
382         }
383         verify(mockedStatement, times(1)).getMoreResults();
384     }
385 
386     @Test
387     void testGetMoreResultsInteger() throws Exception {
388         try {
389             delegatingStatement.getMoreResults(1);
390         } catch (final SQLException e) {
391         }
392         verify(mockedStatement, times(1)).getMoreResults(1);
393     }
394 
395     @Test
396     void testGetQueryTimeout() throws Exception {
397         try {
398             delegatingStatement.getQueryTimeout();
399         } catch (final SQLException e) {
400         }
401         verify(mockedStatement, times(1)).getQueryTimeout();
402     }
403 
404     @Test
405     void testGetResultSet() throws Exception {
406         try {
407             delegatingStatement.getResultSet();
408         } catch (final SQLException e) {
409         }
410         verify(mockedStatement, times(1)).getResultSet();
411     }
412 
413     @Test
414     void testGetResultSetConcurrency() throws Exception {
415         try {
416             delegatingStatement.getResultSetConcurrency();
417         } catch (final SQLException e) {
418         }
419         verify(mockedStatement, times(1)).getResultSetConcurrency();
420     }
421 
422     @Test
423     void testGetResultSetHoldability() throws Exception {
424         try {
425             delegatingStatement.getResultSetHoldability();
426         } catch (final SQLException e) {
427         }
428         verify(mockedStatement, times(1)).getResultSetHoldability();
429     }
430 
431     @Test
432     void testGetResultSetType() throws Exception {
433         try {
434             delegatingStatement.getResultSetType();
435         } catch (final SQLException e) {
436         }
437         verify(mockedStatement, times(1)).getResultSetType();
438     }
439 
440     @Test
441     void testGetUpdateCount() throws Exception {
442         try {
443             delegatingStatement.getUpdateCount();
444         } catch (final SQLException e) {
445         }
446         verify(mockedStatement, times(1)).getUpdateCount();
447     }
448 
449     @Test
450     void testGetWarnings() throws Exception {
451         try {
452             delegatingStatement.getWarnings();
453         } catch (final SQLException e) {
454         }
455         verify(mockedStatement, times(1)).getWarnings();
456     }
457 
458     /**
459      * This method is a bit special, and call isClosed in the delegate object itself, not in the wrapped statement.
460      *
461      * @throws Exception
462      */
463     @Test
464     void testIsClosed() throws Exception {
465         try {
466             delegatingStatement.isClosed();
467         } catch (final SQLException e) {
468         }
469         verify(mockedStatement, times(0)).isClosed();
470     }
471 
472     @Test
473     void testIsCloseOnCompletion() throws Exception {
474         try {
475             delegatingStatement.isCloseOnCompletion();
476         } catch (final SQLException e) {
477         }
478         verify(mockedStatement, times(1)).isCloseOnCompletion();
479     }
480 
481     @Test
482     void testIsPoolable() throws Exception {
483         try {
484             delegatingStatement.isPoolable();
485         } catch (final SQLException e) {
486         }
487         verify(mockedStatement, times(1)).isPoolable();
488     }
489 
490     @Test
491     void testIsWrapperFor() throws Exception {
492         final TesterConnection tstConn = new TesterConnection("test", "test");
493         final TesterStatement tstStmt = new TesterStatementNonWrapping(tstConn);
494         final DelegatingConnection<TesterConnection> dconn = new DelegatingConnection<>(tstConn);
495         final DelegatingStatement stamt = new DelegatingStatement(dconn, tstStmt);
496 
497         final Class<?> stmtProxyClass = Proxy.getProxyClass(this.getClass().getClassLoader(), Statement.class);
498 
499         assertTrue(stamt.isWrapperFor(DelegatingStatement.class));
500         assertTrue(stamt.isWrapperFor(TesterStatement.class));
501         assertFalse(stamt.isWrapperFor(stmtProxyClass));
502 
503         stamt.close();
504     }
505 
506     @Test
507     void testSetCursorNameString() throws Exception {
508         try {
509             delegatingStatement.setCursorName("foo");
510         } catch (final SQLException e) {
511         }
512         verify(mockedStatement, times(1)).setCursorName("foo");
513     }
514 
515     @Test
516     void testSetEscapeProcessingBoolean() throws Exception {
517         try {
518             delegatingStatement.setEscapeProcessing(Boolean.TRUE);
519         } catch (final SQLException e) {
520         }
521         verify(mockedStatement, times(1)).setEscapeProcessing(Boolean.TRUE);
522     }
523 
524     @Test
525     void testSetFetchDirectionInteger() throws Exception {
526         try {
527             delegatingStatement.setFetchDirection(1);
528         } catch (final SQLException e) {
529         }
530         verify(mockedStatement, times(1)).setFetchDirection(1);
531     }
532 
533     @Test
534     void testSetFetchSizeInteger() throws Exception {
535         try {
536             delegatingStatement.setFetchSize(1);
537         } catch (final SQLException e) {
538         }
539         verify(mockedStatement, times(1)).setFetchSize(1);
540     }
541 
542     @Test
543     void testSetLargeMaxRowsLong() throws Exception {
544         try {
545             delegatingStatement.setLargeMaxRows(1L);
546         } catch (final SQLException e) {
547         }
548         verify(mockedStatement, times(1)).setLargeMaxRows(1L);
549     }
550 
551     @Test
552     void testSetMaxFieldSizeInteger() throws Exception {
553         try {
554             delegatingStatement.setMaxFieldSize(1);
555         } catch (final SQLException e) {
556         }
557         verify(mockedStatement, times(1)).setMaxFieldSize(1);
558     }
559 
560     @Test
561     void testSetMaxRowsInteger() throws Exception {
562         try {
563             delegatingStatement.setMaxRows(1);
564         } catch (final SQLException e) {
565         }
566         verify(mockedStatement, times(1)).setMaxRows(1);
567     }
568 
569     @Test
570     void testSetPoolableBoolean() throws Exception {
571         try {
572             delegatingStatement.setPoolable(Boolean.TRUE);
573         } catch (final SQLException e) {
574         }
575         verify(mockedStatement, times(1)).setPoolable(Boolean.TRUE);
576     }
577 
578     @Test
579     void testSetQueryTimeoutInteger() throws Exception {
580         try {
581             delegatingStatement.setQueryTimeout(1);
582         } catch (final SQLException e) {
583         }
584         verify(mockedStatement, times(1)).setQueryTimeout(1);
585     }
586 
587     @Test
588     void testWrap() throws SQLException {
589         assertEquals(delegatingStatement, delegatingStatement.unwrap(Statement.class));
590         assertEquals(delegatingStatement, delegatingStatement.unwrap(DelegatingStatement.class));
591         assertEquals(mockedStatement, delegatingStatement.unwrap(mockedStatement.getClass()));
592         assertNull(delegatingStatement.unwrap(String.class));
593         assertTrue(delegatingStatement.isWrapperFor(Statement.class));
594         assertTrue(delegatingStatement.isWrapperFor(DelegatingStatement.class));
595         assertTrue(delegatingStatement.isWrapperFor(mockedStatement.getClass()));
596         assertFalse(delegatingStatement.isWrapperFor(String.class));
597     }
598 }