休眠:是不是可以仅在测试时“保存级联”?
Posted
技术标签:
【中文标题】休眠:是不是可以仅在测试时“保存级联”?【英文标题】:Hibernate : Is it possible to "save cascade" only on test?休眠:是否可以仅在测试时“保存级联”? 【发布时间】:2016-11-30 09:03:40 【问题描述】:我想知道是否可以保存级联我的实体但仅在我运行测试时?
我希望能够保存级联,但仅在我运行测试时。为了测试我的 dao,如果我可以保存级联实体并且不会因为子实体尚未保存而出现错误,这将为我节省大量时间。
@Test
public void addGetEntityTests()
Entity entity1 = ...;
Entity entity2 = ...; //same as entity1
getDao().addEntity(entity1);
assertEquals(entity1, entity2);
谢谢。
【问题讨论】:
【参考方案1】:如果不修改实体声明或您正在测试的查询,您将无法执行您想要实现的目标。
而且您不应该这样做,因为在这种情况下,您的测试执行的逻辑与您的实现不同,而测试应该检查实现是否按预期工作。
如果您在测试开始时需要一个上下文,您应该在您的类的 @Before
方法之前创建此上下文。
您可以通过自己的服务(如果经过测试)或使用 DBunit 等工具的 SQL 将数据注入数据库。
编辑:DBunit 示例
您在评论中解释说在您的对象中设置所有数据是乏味的。所以,我想你有多个行和关系要设置来创建你的上下文。 在这种情况下,您可以使用 DBunit 并分两步进行:
在数据集中写入每一行也很乏味。另一种方法是根据现有数据库的查询动态创建数据集,该数据库包含您要检索的数据。 此步骤将执行一次,以创建您要在单元测试中使用的数据集。 在测试开始前使用这个生成的数据集我使用了来自http://dbunit.sourceforge.net/howto.html 的示例,我稍作改编。
第一步(生成数据集):
public class DatabaseExportSample
public static void main(String[] args) throws Exception
// database connection
Class driverClass = Class.forName("org.hsqldb.jdbcDriver");
Connection jdbcConnection = DriverManager.getConnection(
"jdbc:hsqldb:sample", "sa", "");
IDatabaseConnection connection = new DatabaseConnection(jdbcConnection);
// partial database export
QueryDataSet partialDataSet = new QueryDataSet(connection);
partialDataSet.addTable("FOO", "SELECT * FROM TABLE WHERE COL='VALUE'");
partialDataSet.addTable("BAR");
FlatXmlDataSet.write(partialDataSet, new FileOutputStream("partial.xml"));
// full database export
IDataSet fullDataSet = connection.createDataSet();
FlatXmlDataSet.write(fullDataSet, new FileOutputStream("full.xml"));
// dependent tables database export: export table X and all tables that
// have a PK which is a FK on X, in the right order for insertion
String[] depTableNames =
TablesDependencyHelper.getAllDependentTables( connection, "X" );
IDataSet depDataset = connection.createDataSet( depTableNames );
FlatXmlDataSet.write(depDataSet, new FileOutputStream("dataset.xml"));
它会生成一个xml文件(这里是一个示例):
<!DOCTYPE dataset SYSTEM "dataset.dtd">
<dataset>
<table name="TEST_TABLE">
<column>COL0</column>
<column>COL1</column>
<column>COL2</column>
<row>
<value>row 0 col 0</value>
<value>row 0 col 1</value>
<value>row 0 col 2</value>
</row>
<row>
<null/>
<value>row 1 col 1</value>
<null/>
</row>
</table>
<table name="SECOND_TABLE">
<column>COLUMN0</column>
<column>COLUMN1</column>
<row>
<value>row 0 col 0</value>
<value>row 0 col 1</value>
</row>
</table>
<table name='EMPTY_TABLE'>
<column>COLUMN0</column>
<column>COLUMN1</column>
</table>
</dataset>
第二步(在你的测试数据库中注入这个数据集):
public class SampleTest
@Before
protected void setUp() throws Exception
super.setUp();
// initialize your database connection here
IDatabaseConnection connection = null;
// ...
// initialize your dataset here
IDataSet dataSet = null;
// ...
try1
DatabaseOperation.CLEAN_INSERT.execute(connection, "dataset.xml");
finally
connection.close();
...
// when your test method starts you have the required data in your test database
@Test
public void addGetEntityTests()
Entity entity1 = ...;
getDao().addEntity(entity1);
【讨论】:
是的,但在应用程序中我只想测试“添加”方法。在我的应用程序中,如果子对象不存在,则出现错误是正常的。我已经在 before 方法中添加了子对象,但它真的很乏味...... 如果太繁琐,您应该在 DBunit 数据集中提取所需数据并在调用测试方法之前注入此数据集。如果你有很多行要获取,你甚至可以使用 DBunit 帮助类来初始化它们。我刚刚使用官方文档编辑了我的答案以显示一个简单的示例。以上是关于休眠:是不是可以仅在测试时“保存级联”?的主要内容,如果未能解决你的问题,请参考以下文章