1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.dbunit.junit.jupiter;
22
23 import static org.assertj.core.api.Assertions.assertThat;
24 import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
25
26 import java.sql.Connection;
27 import java.sql.ResultSet;
28 import java.sql.Statement;
29
30 import org.dbunit.DatabaseEnvironment;
31 import org.dbunit.DatabaseProfile;
32 import org.dbunit.DatabaseTesterFactory;
33 import org.dbunit.DefaultDatabaseTester;
34 import org.dbunit.DefaultPrepAndExpectedTestCase;
35 import org.dbunit.IDatabaseTester;
36 import org.dbunit.IOperationListener;
37 import org.dbunit.JdbcDatabaseTester;
38 import org.dbunit.PrepAndExpectedTestCase;
39 import org.dbunit.PrepAndExpectedTestCaseSteps;
40 import org.dbunit.VerifyTableDefinition;
41 import org.dbunit.annotation.DbUnitConfig;
42 import org.dbunit.annotation.DbUnitExpected;
43 import org.dbunit.annotation.DbUnitPrep;
44 import org.dbunit.annotation.DbUnitTestCase;
45 import org.dbunit.annotation.DbUnitVerifyTable;
46 import org.dbunit.database.IDatabaseConnection;
47 import org.dbunit.dataset.IDataSet;
48 import org.dbunit.operation.DatabaseOperation;
49 import org.junit.jupiter.api.Test;
50 import org.junit.jupiter.api.extension.ExtendWith;
51 import org.junit.platform.testkit.engine.EngineTestKit;
52 import org.slf4j.LoggerFactory;
53
54 import ch.qos.logback.classic.Level;
55 import ch.qos.logback.classic.Logger;
56 import ch.qos.logback.classic.spi.ILoggingEvent;
57 import ch.qos.logback.core.read.ListAppender;
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 class DbUnitExtensionSelfManagedTestCaseIT
74 {
75 private static final String TEST_TABLE = "TEST_TABLE";
76
77 @Test
78 void testAfterTestExecution_selfManagedConnectionTestCaseWithoutTesterOverride_runsTheFullLifecycle()
79 throws Exception
80 {
81 final DatabaseEnvironment environment = DatabaseEnvironment.getInstance();
82 final DatabaseProfile profile = environment.getProfile();
83 deleteAllRowsQuietly(environment);
84 SelfManagedSample.testCase = new SelfManagedTestCase(profile);
85
86 final Logger extensionLogger =
87 (Logger) LoggerFactory.getLogger("org.dbunit.junit.jupiter.TesterResolver");
88 final Level originalLevel = extensionLogger.getLevel();
89 extensionLogger.setLevel(Level.DEBUG);
90 final ListAppender<ILoggingEvent> appender = new ListAppender<>();
91 appender.start();
92 extensionLogger.addAppender(appender);
93 try
94 {
95 EngineTestKit.engine("junit-jupiter")
96 .selectors(selectClass(SelfManagedSample.class)).execute().testEvents()
97 .assertStatistics(stats -> stats.started(1).succeeded(1));
98
99 assertThat(appender.list)
100 .as("A @DbUnitTestCase whose type does not override"
101 + " getDatabaseTester()/setDatabaseTester() is the documented"
102 + " self-managed-connection pattern - the resolution round-trip"
103 + " failure must be a diagnostic log, never an exception.")
104 .anyMatch(event -> event.getFormattedMessage().contains("does not round-trip"));
105
106 final IDatabaseConnection verifyConnection = environment.getConnection();
107 assertThat(rowCount(verifyConnection, TEST_TABLE))
108 .as("The composition test case's own cleanupData() (DELETE_ALL on its"
109 + " internal tester) must have run and committed - the @DbUnitExpected"
110 + " verify passing already proves configureTest/preTest/verifyData"
111 + " ran through it end to end.")
112 .isZero();
113 } finally
114 {
115 extensionLogger.detachAppender(appender);
116 appender.stop();
117 extensionLogger.setLevel(originalLevel);
118 deleteAllRowsQuietly(environment);
119 environment.closeConnection();
120 }
121 }
122
123 private static int rowCount(final IDatabaseConnection connection, final String tableName)
124 throws Exception
125 {
126 try (Statement statement = connection.getConnection().createStatement();
127 ResultSet resultSet =
128 statement.executeQuery("SELECT COUNT(*) FROM " + tableName))
129 {
130 resultSet.next();
131 return resultSet.getInt(1);
132 }
133 }
134
135 private static void deleteAllRowsQuietly(final DatabaseEnvironment environment)
136 {
137 try (Statement statement =
138 environment.getConnection().getConnection().createStatement())
139 {
140 statement.execute("DELETE FROM " + TEST_TABLE);
141 } catch (final Exception e)
142 {
143
144 }
145 }
146
147 @ExtendWith(DbUnitExtension.class)
148 @DbUnitConfig(databaseTesterFactory = SelfManagedSample.NoOpTesterFactory.class)
149 static class SelfManagedSample
150 {
151 @DbUnitTestCase
152 static PrepAndExpectedTestCase testCase;
153
154 @Test
155 @DbUnitPrep("annotation-it-prep.xml")
156 @DbUnitExpected(value = "annotation-it-expected.xml",
157 verify = @DbUnitVerifyTable(value = TEST_TABLE,
158 include = {"COLUMN0", "COLUMN1"}))
159 void mutateTheSeededRow(final Connection connection) throws Exception
160 {
161 try (Statement statement = connection.createStatement())
162 {
163 statement.execute("UPDATE " + TEST_TABLE
164 + " SET COLUMN1 = 'after' WHERE COLUMN0 = 'row0'");
165 }
166 }
167
168
169
170
171
172
173 static class NoOpTesterFactory implements DatabaseTesterFactory
174 {
175 @Override
176 public IDatabaseTester getDatabaseTester() throws Exception
177 {
178 final IDatabaseTester tester = new DefaultDatabaseTester(
179 DatabaseEnvironment.getInstance().getConnection());
180 tester.setOperationListener(IOperationListener.NO_OP_OPERATION_LISTENER);
181 return tester;
182 }
183 }
184 }
185
186
187
188
189
190
191
192
193
194 static final class SelfManagedTestCase implements PrepAndExpectedTestCase
195 {
196 private final DefaultPrepAndExpectedTestCase delegate;
197
198 SelfManagedTestCase(final DatabaseProfile profile) throws Exception
199 {
200 final JdbcDatabaseTester tester = new JdbcDatabaseTester(profile.getDriverClass(),
201 profile.getConnectionUrl(), profile.getUser(), profile.getPassword(),
202 profile.getSchema());
203 tester.setTearDownOperation(DatabaseOperation.DELETE_ALL);
204 delegate = new DefaultPrepAndExpectedTestCase(
205 new org.dbunit.util.fileloader.FlatXmlDataFileLoader(), tester);
206 }
207
208 @Override
209 public IDatabaseConnection getReusableConnection() throws Exception
210 {
211 return delegate.getReusableConnection();
212 }
213
214 @Override
215 public void configureTest(final VerifyTableDefinition[] verifyTableDefinitions,
216 final String[] prepDataFiles, final String[] expectedDataFiles) throws Exception
217 {
218 delegate.configureTest(verifyTableDefinitions, prepDataFiles, expectedDataFiles);
219 }
220
221 @Override
222 public void preTest() throws Exception
223 {
224 delegate.preTest();
225 }
226
227 @Override
228 public void preTest(final VerifyTableDefinition[] verifyTables,
229 final String[] prepDataFiles, final String[] expectedDataFiles) throws Exception
230 {
231 delegate.preTest(verifyTables, prepDataFiles, expectedDataFiles);
232 }
233
234 @Override
235 public Object runTest(final VerifyTableDefinition[] verifyTables,
236 final String[] prepDataFiles, final String[] expectedDataFiles,
237 final PrepAndExpectedTestCaseSteps testSteps) throws Exception
238 {
239 return delegate.runTest(verifyTables, prepDataFiles, expectedDataFiles, testSteps);
240 }
241
242 @Override
243 public void postTest() throws Exception
244 {
245 delegate.postTest();
246 }
247
248 @Override
249 public void postTest(final boolean verifyData) throws Exception
250 {
251 delegate.postTest(verifyData);
252 }
253
254 @Override
255 public void verifyData() throws Exception
256 {
257 delegate.verifyData();
258 }
259
260 @Override
261 public void cleanupData() throws Exception
262 {
263 delegate.cleanupData();
264 }
265
266 @Override
267 public IDataSet getPrepDataset()
268 {
269 return delegate.getPrepDataset();
270 }
271
272 @Override
273 public IDataSet getExpectedDataset()
274 {
275 return delegate.getExpectedDataset();
276 }
277 }
278 }