休眠:是否有可能“保存级联”?只有在测试? [英] Hibernate : Is it possible to "save cascade" only on test?

查看:95
本文介绍了休眠:是否有可能“保存级联”?只有在测试?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道是否可以保存级联我的实体,但只有当我运行我的测试?



我希望能够保存级联,但只有在运行我的测试时才可以。为了测试我的dao,它会为我节省很多时间,如果我可以保存级联实体并且不会因为子实体尚未保存而出错。

  @Test 
public void addGetEntityTests(){

Entity entity1 = ...;
实体entity2 = ...; //和entity1相同

getDao()。addEntity(entity1);
assertEquals(entity1,entity2);

谢谢。

解决方案

在不修改实体声明或正在测试的查询的情况下,您无法执行您想要实现的功能。

您不应该这样做,因为在这种情况下,您的测试不会执行与实现相同的逻辑,而测试应按预期检查实现。

如果在测试开始时需要有上下文,则应在 @Before 您的类的方法。

您可以通过自己的服务(如果测试)将数据注入到数据库中,或者使用DBunit工具将数据注入到SQL中。






编辑:以DBunit为例

你的评论,设置您的对象中的所有数据是乏味的。所以,我想你有多个行和关系来设置创建你的上下文。
在这种情况下,您可以使用DBunit并分两步进行:


  • 写入数据集中的每一行也是单调乏味的。另一种方法是在包含要检索的数据的现有数据库上从查询动态创建数据集。
    这一步将被播放一次,以创建您想要在单元测试中使用的数据集。

  • 在测试开始前使用这个生成的数据集



我使用了 http:// dbunit。 sourceforge.net/howto.html ,我略作修改。



第一步(生成你的数据集):

  public class DatabaseExportSample 
{
public static void main(String [] args)throws Exception {
//数据库连接
Class driverClass = Class.forName(org.hsqldb.jdbcDriver);
连接jdbcConnection = DriverManager.getConnection(
jdbc:hsqldb:sample,sa,);
IDatabaseConnection connection = new DatabaseConnection(jdbcConnection);

//部分数据库导出
QueryDataSet partialDataSet = new QueryDataSet(connection);
partialDataSet.addTable(FOO,SELECT * FROM TABLE WHERE COL ='VALUE');
partialDataSet.addTable(BAR);
FlatXmlDataSet.write(partialDataSet,new FileOutputStream(partial.xml));

//完整数据库导出
IDataSet fullDataSet = connection.createDataSet();
FlatXmlDataSet.write(fullDataSet,new FileOutputStream(full.xml));

//依赖表数据库导出:导出表X和所有表
//有一个PK,它是X上的FK,按照正确的插入顺序
String [ ] depTableNames =
TablesDependencyHelper.getAllDependentTables(connection,X);
IDataSet depDataset = connection.createDataSet(depTableNames);
FlatXmlDataSet.write(depDataSet,new FileOutputStream(dataset.xml));
}
}

它会生成一个xml文件(这里是一个示例):

 <!DOCTYPE数据集SYSTEMdataset.dtd> 
< dataset>
< table name =TEST_TABLE>
< column> COL0< / column>
< column> COL1< / column>
< column> COL2< / column>
< row>
<值>第0行col 0< / value>
<值>第0行col 1< / value>
<值>第0行第2列< /值>
< / row>
< row>
< null />
<值>第1行col 1< / value>
< null />
< / row>
< / table>
< table name =SECOND_TABLE>
< column> COLUMN0< / column>
< column> COLUMN1< / column>
< row>
<值>第0行col 0< / value>
<值>第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();

//在这里初始化数据库连接
IDatabaseConnection connection = null;
// ...

//在这里初始化数据集
IDataSet dataSet = null;
// ...

try1
{
DatabaseOperation.CLEAN_INSERT.execute(connection,dataset.xml);
}
finally
{
connection.close();



//当你的测试方法开始时,你的测试数据库中有所需的数据
@Test
public void addGetEntityTests (){
实体entity1 = ...;
getDao()。addEntity(entity1);
}
}


I would like to know if it was possible to save cascade my Entities but only when i was running my tests ?

I want to be able to save cascade but only when i run my tests. For testing my dao it will save me a lot of time if i could just save cascade an entity and not getting an error because sub-entities aren't saved yet.

@Test
public void addGetEntityTests(){

    Entity entity1 = ...;
    Entity entity2 = ...; //same as entity1

    getDao().addEntity(entity1);
    assertEquals(entity1, entity2);

Thank you.

解决方案

You cannot perform what you want to achieve without modifying the entity declaration or the query you are testing.
And you should not do it because in this case, your test doesn't perform the same logic than your implementation while a test should check the implementation works as expected.
If you need to have a context when your test start, you should create this context before in the @Before method of your class.
You can inject data in your database via your own services (if tested) or SQL with tools as DBunit.


Edit: example with DBunit

You explain in your comment that setting all data in your object is tedious. So, I suppose you have multiples rows and relationships to set to create your context. In this case, you may use DBunit and proceed in two steps :

  • writing each line in your dataset will be also tedious. Another way to do is creating dynamically your dataset from queries on a exiting database which contains data you want to retrieve.
    This step will be played once to create the dataset you want to use in your unit tests.
  • use this generated dataset before your test starts

I used examples from http://dbunit.sourceforge.net/howto.html that I slightly adapted.

For the first step (generating your dataset) :

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"));                      
    }
}

It will generate a xml file (here is a sample) :

<!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>

For the second step (injecting this dataset in your test database) :

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);
  }
}

这篇关于休眠:是否有可能“保存级联”?只有在测试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆