4
4
import com .fasterxml .jackson .databind .DeserializationFeature ;
5
5
import com .fasterxml .jackson .databind .ObjectMapper ;
6
6
import java .io .IOException ;
7
- import org .junit .runner .RunWith ;
7
+ import java .io .InputStream ;
8
+ import java .util .*;
9
+ import javax .sql .DataSource ;
10
+ import org .dbunit .database .DatabaseConfig ;
11
+ import org .dbunit .database .DatabaseConnection ;
12
+ import org .dbunit .database .IDatabaseConnection ;
13
+ import org .dbunit .dataset .IDataSet ;
14
+ import org .dbunit .dataset .xml .FlatXmlDataSet ;
15
+ import org .dbunit .operation .DatabaseOperation ;
8
16
import org .springframework .beans .factory .annotation .Autowired ;
9
17
import org .springframework .http .converter .json .MappingJackson2HttpMessageConverter ;
10
18
import org .springframework .test .context .ActiveProfiles ;
11
19
import org .springframework .test .context .ContextConfiguration ;
12
20
import org .springframework .test .context .TestPropertySource ;
13
- import org .springframework .test .context .junit4 .SpringJUnit4ClassRunner ;
21
+ import org .springframework .test .context .junit4 .AbstractTransactionalJUnit4SpringContextTests ;
22
+ import org .springframework .test .context .transaction .AfterTransaction ;
14
23
import org .springframework .test .context .web .WebAppConfiguration ;
15
24
import org .springframework .test .web .servlet .MockMvc ;
16
25
import org .springframework .test .web .servlet .setup .MockMvcBuilders ;
26
+ import org .springframework .transaction .annotation .Propagation ;
27
+ import org .springframework .transaction .annotation .Transactional ;
17
28
import org .springframework .web .context .WebApplicationContext ;
18
29
19
- @ RunWith ( SpringJUnit4ClassRunner . class )
30
+ @ Transactional ( propagation = Propagation . NOT_SUPPORTED )
20
31
@ ContextConfiguration (classes = { BaseTestConfig .class , AppTestConfig .class })
21
32
@ WebAppConfiguration
22
33
@ TestPropertySource ("classpath:common.properties" )
23
34
@ ActiveProfiles ("test" )
24
- public abstract class BaseWebContextSensitiveTest {
35
+ public abstract class BaseWebContextSensitiveTest extends AbstractTransactionalJUnit4SpringContextTests {
25
36
26
37
@ Autowired
27
38
protected WebApplicationContext webApplicationContext ;
28
39
40
+ @ Autowired
41
+ private DataSource dataSource ;
42
+
29
43
protected MockMvc mockMvc ;
30
44
31
- protected void setUp () {
45
+ private Map <String , IDataSet > originalStateCache ;
46
+
47
+ private List <String []> tablesToRestore ;
48
+
49
+ protected BaseWebContextSensitiveTest () {
50
+ this .originalStateCache = new HashMap <>();
51
+ this .tablesToRestore = new ArrayList <>();
52
+ }
53
+
54
+ protected BaseWebContextSensitiveTest (List <String []> tablesToRestore ) {
55
+ this .originalStateCache = new HashMap <>();
56
+ this .tablesToRestore = tablesToRestore != null ? tablesToRestore : new ArrayList <>();
57
+ }
58
+
59
+ protected void setUp () throws Exception {
32
60
mockMvc = MockMvcBuilders .webAppContextSetup (this .webApplicationContext ).build ();
33
61
}
34
62
@@ -44,4 +72,107 @@ public <T> T mapFromJson(String json, Class<T> clazz) throws IOException {
44
72
objectMapper .enable (DeserializationFeature .ACCEPT_SINGLE_VALUE_AS_ARRAY );
45
73
return objectMapper .readValue (json , clazz );
46
74
}
75
+
76
+ /**
77
+ * Executes a dataset with state management - preserves and restores the
78
+ * original state of affected tables after execution.
79
+ */
80
+ protected void executeDataSetWithStateManagement (String datasetFilename ) throws Exception {
81
+ if (datasetFilename == null ) {
82
+ throw new NullPointerException ("Please provide test dataset file to execute!" );
83
+ }
84
+
85
+ IDatabaseConnection connection = null ;
86
+ try {
87
+ connection = new DatabaseConnection (dataSource .getConnection ());
88
+ DatabaseConfig config = connection .getConfig ();
89
+ config .setProperty (DatabaseConfig .FEATURE_ALLOW_EMPTY_FIELDS , true );
90
+
91
+ IDataSet newDataSet = loadDataSet (datasetFilename );
92
+ String [] tableNames = newDataSet .getTableNames ();
93
+
94
+ // Backup current state of affected tables
95
+ IDataSet currentState = connection .createDataSet (tableNames );
96
+ originalStateCache .put (Arrays .toString (tableNames ), currentState );
97
+ tablesToRestore .add (tableNames );
98
+
99
+ executeDataSet (datasetFilename );
100
+ } finally {
101
+ if (connection != null ) {
102
+ connection .close ();
103
+ }
104
+ }
105
+ }
106
+
107
+ /**
108
+ * This method will be called after each transaction to restore the database
109
+ * state
110
+ */
111
+ @ AfterTransaction
112
+ @ SuppressWarnings ("unused" )
113
+ protected void restoreDatabase () throws Exception {
114
+ try {
115
+ for (String [] tableNames : tablesToRestore ) {
116
+ String key = Arrays .toString (tableNames );
117
+ IDataSet originalState = originalStateCache .get (key );
118
+ if (originalState != null ) {
119
+ IDatabaseConnection connection = null ;
120
+ try {
121
+ connection = new DatabaseConnection (dataSource .getConnection ());
122
+ DatabaseConfig config = connection .getConfig ();
123
+ config .setProperty (DatabaseConfig .FEATURE_ALLOW_EMPTY_FIELDS , true );
124
+
125
+ DatabaseOperation .CLEAN_INSERT .execute (connection , originalState );
126
+ } finally {
127
+ if (connection != null ) {
128
+ connection .close ();
129
+ }
130
+ }
131
+ originalStateCache .remove (key );
132
+ }
133
+ }
134
+ } finally {
135
+ originalStateCache .clear ();
136
+ tablesToRestore .clear ();
137
+ }
138
+ }
139
+
140
+ /**
141
+ * Loads a dataset from an XML file.
142
+ */
143
+ private IDataSet loadDataSet (String datasetFilename ) throws Exception {
144
+ try (InputStream inputStream = getClass ().getClassLoader ().getResourceAsStream (datasetFilename )) {
145
+ if (inputStream == null ) {
146
+ throw new IllegalArgumentException ("Dataset file '" + datasetFilename + "' not found in classpath" );
147
+ }
148
+ return new FlatXmlDataSet (inputStream );
149
+ }
150
+ }
151
+
152
+ /**
153
+ * Executes a dataset from an XML file.
154
+ */
155
+ protected void executeDataSet (String datasetFilename ) throws Exception {
156
+ if (datasetFilename == null ) {
157
+ throw new NullPointerException ("please provide test dataset file to execute!" );
158
+ }
159
+
160
+ InputStream inputStream = getClass ().getClassLoader ().getResourceAsStream (datasetFilename );
161
+ try (inputStream ) {
162
+ if (inputStream == null ) {
163
+ throw new IllegalArgumentException ("Dataset file '" + datasetFilename + "' not found in classpath" );
164
+ }
165
+ IDatabaseConnection connection = new DatabaseConnection (dataSource .getConnection ());
166
+
167
+ DatabaseConfig config = connection .getConfig ();
168
+ config .setProperty (DatabaseConfig .FEATURE_ALLOW_EMPTY_FIELDS , true );
169
+ IDataSet dataset = new FlatXmlDataSet (inputStream );
170
+
171
+ try {
172
+ DatabaseOperation .REFRESH .execute (connection , dataset );
173
+ } finally {
174
+ connection .close ();
175
+ }
176
+ }
177
+ }
47
178
}
0 commit comments