java 如何使用 dbUnit 将数据库恢复到初始状态?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3813684/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to revert the database back to the initial state using dbUnit?
提问by Igor Mukhin
I am new to automated testing and dbUnit. So I would appreciate your advice.
我是自动化测试和 dbUnit 的新手。所以我很感激你的建议。
I am going to create a test suite, that will run the following way:
我将创建一个测试套件,它将按以下方式运行:
- create an in-memory H2 database
- run DDL scripts to create tables
- run dbUnit to insert initial data (let's call it STATE0) that will be used by all tests.
- run tests
- 创建内存 H2 数据库
- 运行 DDL 脚本来创建表
- 运行 dbUnit 以插入所有测试将使用的初始数据(我们称之为STATE0)。
- 运行测试
Till there it looks nice for me, but what I don't understand, is how do I revert the database to the STATE0after a test run and changed the data?
直到那里它对我来说看起来不错,但我不明白的是,如何在测试运行并更改数据后将数据库恢复到STATE0?
Can I do it with dbUnit?
Or with something else?
Should I recreate the database before each test?
我可以用 dbUnit 来做吗?
还是用别的东西?
我应该在每次测试之前重新创建数据库吗?
Simple not commiting transactions in tests is not appropriate for me, because the tests will eventually run more than one transaction over may be more than one database connection.
简单的在测试中不提交事务对我来说是不合适的,因为测试最终会运行多个事务,可能是多个数据库连接。
采纳答案by Péter T?r?k
DBUnit can do the work four you automatically if you write your @BeforeClass
, @Before
and @After
methods properly. E.g. in our project, using Derby, one such test case looks like
如果您正确编写@BeforeClass
,@Before
和@After
方法,DBUnit 可以自动完成四项工作。例如,在我们的项目中,使用 Derby,一个这样的测试用例看起来像
public class MyTest {
protected static IDataSet getDataSet() throws Exception {
URL url = MyTest.class.getClassLoader().getResource("MyDataSet.xml");
return new XmlDataSet(new FileInputStream(url.getPath()));
}
private static JdbcDatabaseTester databaseTester;
@BeforeClass
public static void setUpClass() throws Exception {
// Init test environment, session etc.
databaseTester = new JdbcDatabaseTester(
"org.apache.derby.jdbc.ClientDriver",
"jdbc:derby://localhost:1527/myschema",
"username", "password");
databaseTester.setDataSet(getDataSet());
}
@AfterClass
public static void tearDownClass() {
// Close session etc.
}
@Before
public void setUp() throws Exception {
databaseTester.onSetup();
}
@After
public void tearDown() throws Exception {
databaseTester.onTearDown();
}
@Test
public void test() throws Exception { ... }
}
This code puts back (a subset of) the DB schema to the state defined by MyDataSet.xml
after each test. (Note that, as @Pascal commented, the reset may not always be full - if a test modifies a table which is not in the dataset, it won't be affected by the @Before
/ @After
methods.)
此代码将 DB 模式(的子集)放回MyDataSet.xml
每个测试后定义的状态。(请注意,正如@Pascal 所评论的,重置可能并不总是完整的 - 如果测试修改了不在数据集中的表,它不会受到@Before
/@After
方法的影响。)
回答by Zofren
To initialize the database to the initial dataset, just implement these methods in your test case :
要将数据库初始化为初始数据集,只需在您的测试用例中实现这些方法:
@Override
protected DatabaseOperation getSetUpOperation() throws Exception
{
return DatabaseOperation.CLEAN_INSERT; // by default (will do DELETE_ALL + INSERT)
}
@Override
protected DatabaseOperation getTearDownOperation() throws Exception
{
return DatabaseOperation.NONE; // by default
}
You may have foreign keys constraints if some of your tests insert rows in an empty table (not defined in initial dataset for example).
如果您的某些测试在空表中插入行(例如未在初始数据集中定义),则您可能有外键约束。
Just add this empty table in your dataset without any row :
只需在您的数据集中添加这个空表,没有任何行:
<mydb_mypopulatedtable id="1" name="toto" alias="funky"/>
<mydb_mypopulatedtable id="2" name="titi" alias="groovy"/>
<mydb_mypopulatedtable id="3" name="tutu" alias="creepy"/>
<mydb_myemptytable />
Here, myemptytable has a foreign key to mypopulatedtable. If myemptytable was not defined, DBUnit would try to delete the mypopulatedtable but will fail because of the constraint. If defined, DBUnit will delete myemptytable rows before.
在这里,myemptytable 有一个指向 mypopulatedtable 的外键。如果未定义 myemptytable,DBUnit 将尝试删除 mypopulatedtable,但会因约束而失败。如果定义,DBUnit 将删除之前的 myemptytable 行。