View Javadoc
1   /*
2    *
3    * The DbUnit Database Testing Framework
4    * Copyright (C)2002-2004, DbUnit.org
5    *
6    * This library is free software; you can redistribute it and/or
7    * modify it under the terms of the GNU Lesser General Public
8    * License as published by the Free Software Foundation; either
9    * version 2.1 of the License, or (at your option) any later version.
10   *
11   * This library is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   * Lesser General Public License for more details.
15   *
16   * You should have received a copy of the GNU Lesser General Public
17   * License along with this library; if not, write to the Free Software
18   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19   *
20   */
21  
22  package org.dbunit.database.statement;
23  
24  import static org.assertj.core.api.Assertions.assertThat;
25  
26  import java.sql.SQLException;
27  import java.util.Objects;
28  import java.util.concurrent.atomic.AtomicInteger;
29  
30  import org.dbunit.database.IDatabaseConnection;
31  
32  /**
33   * Mock implementation of {@link IStatementFactory} for use in unit tests.
34   * Tracks the number of statement creation calls and delegates to a configured
35   * {@link IBatchStatement}.
36   *
37   * <p>Use {@link #forSingleBatch(String...)} to create a fully-wired factory
38   * expecting exactly one batch execution of the given SQL statements, reducing
39   * per-test setup boilerplate.
40   *
41   * @author Manuel Laflamme
42   * @version $Revision$
43   * @since Mar 16, 2002
44   */
45  public class MockStatementFactory implements IStatementFactory
46  {
47      private IBatchStatement _batchStatement = null;
48      // private IPreparedBatchStatement _preparedBatchStatement = null;
49      private Integer _expectedCreateStatementCalls;
50      private Integer _expectedCreatePreparedStatementCalls;
51      private AtomicInteger _createStatementCalls = new AtomicInteger();
52      private AtomicInteger _createPreparedStatementCalls = new AtomicInteger();
53  
54      /**
55       * Creates a {@link MockStatementFactory} pre-wired with a {@link MockBatchStatement}
56       * expecting exactly the given SQL statements in a single batch execution.
57       * Equivalent to manually creating and configuring both a {@link MockBatchStatement}
58       * and a {@link MockStatementFactory}, but in one call.
59       *
60       * <p>Call {@link #getBatchStatement()} on the returned factory to access the
61       * underlying {@link MockBatchStatement} for additional assertions such as
62       * {@link MockBatchStatement#getCapturedSql()}.
63       *
64       * @param expectedSql the SQL strings expected to be batched, in order
65       * @return a fully configured factory ready for use in a test
66       */
67      public static MockStatementFactory forSingleBatch(final String... expectedSql)
68      {
69          final MockBatchStatement statement = new MockBatchStatement();
70          statement.addExpectedBatchStrings(expectedSql);
71          statement.setExpectedExecuteBatchCalls(1);
72          statement.setExpectedClearBatchCalls(1);
73          statement.setExpectedCloseCalls(1);
74  
75          final MockStatementFactory factory = new MockStatementFactory();
76          factory.setExpectedCreatePreparedStatementCalls(1);
77          factory.setupStatement(statement);
78          return factory;
79      }
80  
81      /**
82       * Returns the {@link MockBatchStatement} configured via {@link #setupStatement(IBatchStatement)}.
83       * Useful after using {@link #forSingleBatch(String...)} to access the underlying
84       * statement for pattern-based assertions via {@link MockBatchStatement#getCapturedSql()}.
85       *
86       * @return the configured batch statement, or {@code null} if none was set
87       */
88      public MockBatchStatement getBatchStatement()
89      {
90          return (MockBatchStatement) _batchStatement;
91      }
92  
93      public void setupStatement(final IBatchStatement batchStatement)
94      {
95          _batchStatement = batchStatement;
96      }
97  
98      // public void setupPreparedStatement(IPreparedBatchStatement
99      // preparedBatchStatement)
100     // {
101     // _preparedBatchStatement = preparedBatchStatement;
102     // }
103 
104     public void setExpectedCreateStatementCalls(final int callsCount)
105     {
106         _expectedCreateStatementCalls = callsCount;
107     }
108 
109     public void setExpectedCreatePreparedStatementCalls(final int callsCount)
110     {
111         _expectedCreatePreparedStatementCalls = callsCount;
112     }
113 
114     public void verify()
115     {
116         if (!Objects.isNull(_expectedCreateStatementCalls))
117         {
118             assertThat(_createStatementCalls.get())
119                     .isEqualTo(_expectedCreateStatementCalls);
120         }
121         if (!Objects.isNull(_expectedCreatePreparedStatementCalls))
122         {
123             assertThat(_createPreparedStatementCalls.get())
124                     .isEqualTo(_expectedCreatePreparedStatementCalls);
125         }
126     }
127 
128     ////////////////////////////////////////////////////////////////////////////
129     // IStatementFactory interface
130 
131     @Override
132     public IBatchStatement createBatchStatement(
133             final IDatabaseConnection connection) throws SQLException
134     {
135         _createStatementCalls.incrementAndGet();
136         return _batchStatement;
137     }
138 
139     @Override
140     public IPreparedBatchStatement createPreparedBatchStatement(
141             final String sql, final IDatabaseConnection connection)
142             throws SQLException
143     {
144         _createPreparedStatementCalls.incrementAndGet();
145         return new BatchStatementDecorator(sql, _batchStatement);
146     }
147 }