AbstractDbTest.java

1
package com.reallifedeveloper.tools.test.database.dbunit;
2
3
import java.io.IOException;
4
import java.util.Arrays;
5
import java.util.Optional;
6
7
import javax.sql.DataSource;
8
9
import org.checkerframework.checker.nullness.qual.Nullable;
10
import org.dbunit.dataset.DataSetException;
11
import org.dbunit.dataset.IDataSet;
12
import org.dbunit.dataset.datatype.IDataTypeFactory;
13
import org.dbunit.ext.mssql.InsertIdentityOperation;
14
import org.dbunit.operation.DatabaseOperation;
15
import org.junit.jupiter.api.AfterEach;
16
import org.junit.jupiter.api.BeforeEach;
17
import org.springframework.transaction.annotation.Transactional;
18
19
/**
20
 * Base class for DBUnit tests.
21
 * <p>
22
 * An example of how to use this class:
23
 *
24
 * <pre>
25
 * &#64;ExtendWith(SpringExtension.class)
26
 * &#64;ContextConfiguration(classes = TestConfiguration.class)
27
 * public class MyDbTest extends AbstractDbTest {
28
 *     &#64;Autowired
29
 *     private DataSource ds;
30
 *
31
 *     &#64;Autowired
32
 *     private IDataTypeFactory dataTypeFactory;
33
 *
34
 *     public MyDbTest() {
35
 *         super(null, "/dbunit/myschema.dtd", "/dbunit/dataset1.xml", "/dbunit/dataset2.xml");
36
 *     }
37
 *
38
 *     &#64;Test
39
 *     public void myTest() {
40
 *         ...
41
 *     }
42
 *
43
 *     &#64;Override
44
 *     protected DataSource getDataSource() { return ds; }
45
 *
46
 *     &#64;Override
47
 *     protected IDataTypeFactory getDataTypeFactory() { return dataTypeFactory; }
48
 * }
49
 * </pre>
50
 *
51
 * @author RealLifeDeveloper
52
 *
53
 */
54
@Transactional
55
public abstract class AbstractDbTest {
56
57
    /**
58
     * The default operation to perform before executing each test.
59
     */
60
    public static final DatabaseOperation DEFAULT_SETUP_OPERATION = InsertIdentityOperation.CLEAN_INSERT;
61
62
    /**
63
     * The default operation to perform after executing each test.
64
     */
65
    public static final DatabaseOperation DEFAULT_TEARDOWN_OPERATION = DatabaseOperation.NONE;
66
67
    private Optional<String> schemaName;
68
    private Optional<String> dataSetDtdResourceName;
69
    private String[] dataSetResourceNames;
70
71
    private DbTestHelper dbTestHelper;
72
73
    /**
74
     * Creates a new test instance, using the given schema and reading the DBUnit XML file found in the given classpath resource.
75
     *
76
     * @param schemaName          name of the database schema, or {@code null}
77
     * @param dataSetResourceName name of the classpath resource that contains DBUnit XML
78
     */
79
    protected AbstractDbTest(String schemaName, String dataSetResourceName) {
80
        this(schemaName, null, dataSetResourceName);
81
    }
82
83
    /**
84
     * Creates a new test instance, using the given schema and reading the DBUnit XML files and DTD found in the given classpath resources.
85
     *
86
     * @param schemaName             name of the database schema, or {@code null}
87
     * @param dataSetDtdResourceName name of the classpath resource containing the DTD for the XML, or {@code null} to not validate
88
     * @param dataSetResourceNames   names of classpath resources containing DBUnit XML
89
     */
90
    protected AbstractDbTest(String schemaName, @Nullable String dataSetDtdResourceName, String... dataSetResourceNames) {
91 1 1. <init> : negated conditional → KILLED
        if (dataSetResourceNames == null) {
92
            throw new IllegalArgumentException("dataSetResourceName must not be null");
93
        }
94
        this.schemaName = Optional.ofNullable(schemaName);
95
        this.dataSetDtdResourceName = Optional.ofNullable(dataSetDtdResourceName);
96
        this.dataSetResourceNames = dataSetResourceNames.clone();
97
    }
98
99
    /**
100
     * Called before each test case to insert test data into the database.
101
     *
102
     * @throws Exception if something goes wrong
103
     */
104
    @BeforeEach
105
    @SuppressWarnings("PMD.SignatureDeclareThrowsException")
106
    public void setUpDatabase() throws Exception {
107
        dbTestHelper = new DbTestHelper(getDataSource(), getDataSet(), getSchemaName(), getDataTypeFactory());
108 1 1. setUpDatabase : removed call to com/reallifedeveloper/tools/test/database/dbunit/DbTestHelper::setSetUpOperation → SURVIVED
        dbTestHelper.setSetUpOperation(getSetUpOperation());
109 1 1. setUpDatabase : removed call to com/reallifedeveloper/tools/test/database/dbunit/DbTestHelper::setTearDownOperation → SURVIVED
        dbTestHelper.setTearDownOperation(getTearDownOperation());
110 1 1. setUpDatabase : removed call to com/reallifedeveloper/tools/test/database/dbunit/DbTestHelper::init → SURVIVED
        dbTestHelper.init();
111
    }
112
113
    /**
114
     * Called after each test case to clean the database from test data.
115
     *
116
     * @throws Exception if something goes wrong
117
     */
118
    @AfterEach
119
    @SuppressWarnings("PMD.SignatureDeclareThrowsException")
120
    public void tearDownDatabase() throws Exception {
121 1 1. tearDownDatabase : negated conditional → KILLED
        if (dbTestHelper != null) {
122 1 1. tearDownDatabase : removed call to com/reallifedeveloper/tools/test/database/dbunit/DbTestHelper::clean → SURVIVED
            dbTestHelper.clean();
123
        }
124
    }
125
126
    /**
127
     * Gives the name of the database schema. Can be {@code null}.
128
     *
129
     * @return the database schema name
130
     */
131
    protected Optional<String> getSchemaName() {
132 1 1. getSchemaName : replaced return value with Optional.empty for com/reallifedeveloper/tools/test/database/dbunit/AbstractDbTest::getSchemaName → RUN_ERROR
        return schemaName;
133
    }
134
135
    /**
136
     * Gives the name of the resource containing the DTD for test data files.
137
     *
138
     * @return the name of the DTD resource
139
     */
140
    protected Optional<String> getDataSetDtdResourceName() {
141 1 1. getDataSetDtdResourceName : replaced return value with Optional.empty for com/reallifedeveloper/tools/test/database/dbunit/AbstractDbTest::getDataSetDtdResourceName → KILLED
        return dataSetDtdResourceName;
142
    }
143
144
    /**
145
     * Gives the names of the resources containing test data.
146
     *
147
     * @return the names of the test data resources
148
     */
149
    protected String[] getDataSetResourceNames() {
150 1 1. getDataSetResourceNames : replaced return value with null for com/reallifedeveloper/tools/test/database/dbunit/AbstractDbTest::getDataSetResourceNames → KILLED
        return Arrays.copyOf(dataSetResourceNames, dataSetResourceNames.length);
151
    }
152
153
    /**
154
     * Gives the data set used by DbUnit when testing. The default implementation reads XML files from the classpath resources pointed to by
155
     * the {@code dataSetResourceNames} property, validating using the DTD pointed to by the {@code dataSetDtdResourceName} property.
156
     * <p>
157
     * Override this method if you want to provide the DbUnit test data in some other way.
158
     *
159
     * @return the test data set
160
     *
161
     * @throws DataSetException if some resource if malformed
162
     * @throws IOException      if reading a resource failed
163
     */
164
    protected IDataSet getDataSet() throws DataSetException, IOException {
165
        String dtdResourceName = getDataSetDtdResourceName().orElse(null);
166 1 1. getDataSet : replaced return value with null for com/reallifedeveloper/tools/test/database/dbunit/AbstractDbTest::getDataSet → KILLED
        return DbTestHelper.readDataSetFromClasspath(dtdResourceName, getDataSetResourceNames());
167
    }
168
169
    /**
170
     * Override this to point to your datasource. The datasource could, e.g., be injected by Spring.
171
     *
172
     * @return the {@code DataSource} to use
173
     */
174
    protected abstract DataSource getDataSource();
175
176
    /**
177
     * Gives the DbUnit {@code IDataTypeFactory} that matches the database used for testing, or {@code null} if the database type is left
178
     * unspecified. If left unspecified, DbUnit will probably issue a lot of warnings about "potential problems".
179
     * <p>
180
     * The default implementation returns {@code null}. Override this to return the right {@code IDataTypeFactory} for your database, e.g.,
181
     * {@code org.dbunit.ext.mysql.MySqlDataTypeFactory} or {@code org.dbunit.ext.oracle.Oracle10DataTypeFactory}.
182
     * <p>
183
     * To make it easy to change to use a different database, the factory could be configured by Spring and injected into your test case.
184
     *
185
     * @return the{@code IDataTypeFactory} to use
186
     */
187
    protected Optional<IDataTypeFactory> getDataTypeFactory() {
188
        return Optional.empty();
189
    }
190
191
    /**
192
     * Gives the operation to perform before executing each test.
193
     * <p>
194
     * The default is {@link #DEFAULT_SETUP_OPERATION}. Override this method to change this behavior.
195
     *
196
     * @return the setup operation to perform
197
     */
198
    protected DatabaseOperation getSetUpOperation() {
199 1 1. getSetUpOperation : replaced return value with null for com/reallifedeveloper/tools/test/database/dbunit/AbstractDbTest::getSetUpOperation → KILLED
        return DEFAULT_SETUP_OPERATION;
200
    }
201
202
    /**
203
     * Gives the operation to perform after executing each test.
204
     * <p>
205
     * The default is {@link #DEFAULT_TEARDOWN_OPERATION}. Override this method to change this behavior.
206
     *
207
     * @return the setup operation to perform
208
     */
209
    protected DatabaseOperation getTearDownOperation() {
210 1 1. getTearDownOperation : replaced return value with null for com/reallifedeveloper/tools/test/database/dbunit/AbstractDbTest::getTearDownOperation → KILLED
        return DEFAULT_TEARDOWN_OPERATION;
211
    }
212
213
    /**
214
     * Make finalize method final to avoid "Finalizer attacks" and corresponding SpotBugs warning (CT_CONSTRUCTOR_THROW).
215
     *
216
     * @see <a href="https://wiki.sei.cmu.edu/confluence/display/java/OBJ11-J.+Be+wary+of+letting+constructors+throw+exceptions">
217
     *      Explanation of finalizer attack</a>
218
     */
219
    @Override
220
    @SuppressWarnings({ "deprecation", "removal", "Finalize", "checkstyle:NoFinalizer", "PMD.EmptyFinalizer",
221
            "PMD.EmptyMethodInAbstractClassShouldBeAbstract" })
222
    protected final void finalize() throws Throwable {
223
        // Do nothing
224
    }
225
226
}

Mutations

91

1.1
Location : <init>
Killed by : com.reallifedeveloper.tools.test.database.dbunit.DbTestTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.tools.test.database.dbunit.DbTestTest]/[method:constructorThreeArgsNullDataSetResourceNames()]
negated conditional → KILLED

108

1.1
Location : setUpDatabase
Killed by : none
removed call to com/reallifedeveloper/tools/test/database/dbunit/DbTestHelper::setSetUpOperation → SURVIVED
Covering tests

109

1.1
Location : setUpDatabase
Killed by : none
removed call to com/reallifedeveloper/tools/test/database/dbunit/DbTestHelper::setTearDownOperation → SURVIVED
Covering tests

110

1.1
Location : setUpDatabase
Killed by : none
removed call to com/reallifedeveloper/tools/test/database/dbunit/DbTestHelper::init → SURVIVED
Covering tests

121

1.1
Location : tearDownDatabase
Killed by : com.reallifedeveloper.tools.test.database.dbunit.DbTestTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.tools.test.database.dbunit.DbTestTest]/[method:tearDownBeforeSetUp()]
negated conditional → KILLED

122

1.1
Location : tearDownDatabase
Killed by : none
removed call to com/reallifedeveloper/tools/test/database/dbunit/DbTestHelper::clean → SURVIVED
Covering tests

132

1.1
Location : getSchemaName
Killed by : none
replaced return value with Optional.empty for com/reallifedeveloper/tools/test/database/dbunit/AbstractDbTest::getSchemaName → RUN_ERROR

141

1.1
Location : getDataSetDtdResourceName
Killed by : com.reallifedeveloper.tools.test.database.dbunit.DbTestTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.tools.test.database.dbunit.DbTestTest]/[method:constructorThreeArgsNullDataSetResourceNames()]
replaced return value with Optional.empty for com/reallifedeveloper/tools/test/database/dbunit/AbstractDbTest::getDataSetDtdResourceName → KILLED

150

1.1
Location : getDataSetResourceNames
Killed by : com.reallifedeveloper.tools.test.database.dbunit.DbTestTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.tools.test.database.dbunit.DbTestTest]/[method:constructorThreeArgsNullDataSetResourceNames()]
replaced return value with null for com/reallifedeveloper/tools/test/database/dbunit/AbstractDbTest::getDataSetResourceNames → KILLED

166

1.1
Location : getDataSet
Killed by : com.reallifedeveloper.tools.test.database.dbunit.DbTestTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.tools.test.database.dbunit.DbTestTest]/[method:constructorThreeArgsNullDataSetResourceNames()]
replaced return value with null for com/reallifedeveloper/tools/test/database/dbunit/AbstractDbTest::getDataSet → KILLED

199

1.1
Location : getSetUpOperation
Killed by : com.reallifedeveloper.tools.test.database.dbunit.DbTestTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.tools.test.database.dbunit.DbTestTest]/[method:constructorThreeArgsNullDataSetResourceNames()]
replaced return value with null for com/reallifedeveloper/tools/test/database/dbunit/AbstractDbTest::getSetUpOperation → KILLED

210

1.1
Location : getTearDownOperation
Killed by : com.reallifedeveloper.tools.test.database.dbunit.DbTestTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.tools.test.database.dbunit.DbTestTest]/[method:constructorThreeArgsNullDataSetResourceNames()]
replaced return value with null for com/reallifedeveloper/tools/test/database/dbunit/AbstractDbTest::getTearDownOperation → KILLED

Active mutators

Tests examined


Report generated by PIT 1.20.2