/** Test for clear statement caches. */
  @Test
  public void testClearStatementCaches() {

    testClass.statementCachingEnabled = true;
    mockPreparedStatementCache.clear();
    expectLastCall().once();
    mockCallableStatementCache.clear();
    expectLastCall().once();

    replay(mockPreparedStatementCache, mockCallableStatementCache);
    testClass.clearStatementCaches(true);
    verify(mockPreparedStatementCache, mockCallableStatementCache);
    reset(mockPreparedStatementCache, mockCallableStatementCache);

    mockPool.closeConnectionWatch = true;
    mockPreparedStatementCache.checkForProperClosure();
    expectLastCall().once();
    mockCallableStatementCache.checkForProperClosure();
    expectLastCall().once();

    replay(mockPreparedStatementCache, mockCallableStatementCache);
    testClass.clearStatementCaches(false);
    verify(mockPreparedStatementCache, mockCallableStatementCache);
  }
  /**
   * Test routine for callable statements.
   *
   * @param args
   * @throws SecurityException
   * @throws NoSuchFieldException
   * @throws IllegalArgumentException
   * @throws IllegalAccessException
   * @throws NoSuchMethodException
   * @throws InvocationTargetException
   */
  @SuppressWarnings("unchecked")
  private void callableStatementTest(Class... args)
      throws SecurityException, NoSuchFieldException, IllegalArgumentException,
          IllegalAccessException, NoSuchMethodException, InvocationTargetException {
    Object[] params = new Object[args.length];
    for (int i = 0; i < args.length; i++) {
      params[i] = CommonTestUtils.instanceMap.get(args[i]);
    }

    Method prepCallMethod = testClass.getClass().getMethod("prepareCall", args);

    CallableStatementHandle mockStatement = createNiceMock(CallableStatementHandle.class);
    ConcurrentLinkedQueue<Statement> mockStatementHandles =
        createNiceMock(ConcurrentLinkedQueue.class);

    testClass.renewConnection(); // logically open the connection

    // fetching a statement that is found in cache. Statement should be returned and marked as being
    // (logically) open
    doStatementMock(mockCallableStatementCache, mockStatement, params, args);

    //
    //	expect(mockCallableStatementCache.get((String)anyObject())).andReturn(mockStatement).anyTimes();

    ((StatementHandle) mockStatement).setLogicallyOpen();
    expectLastCall();
    replay(mockStatement, mockCallableStatementCache);
    prepCallMethod.invoke(testClass, params);
    verify(mockStatement, mockCallableStatementCache);

    reset(mockStatement, mockCallableStatementCache, mockStatementHandles);

    // test for a cache miss
    doStatementMock(mockCallableStatementCache, null, params, args);

    // we should be creating the preparedStatement because it's not in the cache
    expect(prepCallMethod.invoke(mockConnection, params)).andReturn(mockStatement);
    // we should be tracking this statement
    expect(mockStatementHandles.add(mockStatement)).andReturn(true);

    replay(mockStatement, mockCallableStatementCache, mockConnection, mockStatementHandles);
    prepCallMethod.invoke(testClass, params);
    verify(mockStatement, mockCallableStatementCache, mockConnection);

    // test for cache miss + sql exception
    reset(mockStatement, mockCallableStatementCache, mockConnection);

    Method mockConnectionPrepareCallMethod =
        mockConnection.getClass().getMethod("prepareCall", args);

    //		expect(mockCallableStatementCache.get((String)anyObject())).andReturn(null).once();
    doStatementMock(mockCallableStatementCache, null, params, args);

    // we should be creating the preparedStatement because it's not in the cache
    expect(mockConnectionPrepareCallMethod.invoke(mockConnection, params))
        .andThrow(new SQLException("test", "Z"));

    replay(mockStatement, mockCallableStatementCache, mockConnection);
    try {
      prepCallMethod.invoke(testClass, params);
      fail("Should have thrown an exception");
    } catch (Throwable t) {
      // do nothing
    }

    verify(mockStatement, mockCallableStatementCache, mockConnection);

    // test for no cache defined
    reset(mockStatement, mockCallableStatementCache, mockConnection);
    boolean oldState = testClass.statementCachingEnabled;

    testClass.statementCachingEnabled = false;

    // we should be creating the preparedStatement because it's not in the cache
    expect(mockConnectionPrepareCallMethod.invoke(mockConnection, params)).andReturn(mockStatement);

    replay(mockStatement, mockCallableStatementCache, mockConnection);
    prepCallMethod.invoke(testClass, params);
    verify(mockStatement, mockCallableStatementCache, mockConnection);
    // restore sanity
    testClass.statementCachingEnabled = oldState;

    reset(mockStatement, mockCallableStatementCache, mockConnection);
  }