标签: dbunit

数据库单元测试框架?

在我的项目中,我使用了spring,jpa和PostgreSQL DB,我在DB中有很多表,我需要对所有这些表进行单元测试.

是否有任何框架在每次测试完成后回滚所有事务,因此每个测试都会有新的/相同的DB数据进行测试.这种方式在所有测试执行之后,DB模式的数据将保持原样.

有什么建议吗?

我对DBUnit有所了解,但是我需要为每个测试编写每个输入数据的.xml文件,需要在setup()中插入数据并清除/删除tearDown()中的数据,但似乎没有更好的策略对我来说.

任何建议表示赞赏.谢谢.

java spring dbunit unit-testing jpa

7
推荐指数
1
解决办法
5386
查看次数

DBUnit不会在每个方法之后清理并插入数据库,因此测试不是独立的

我有一个DAO类的测试,我使用DBUnit来创建和填充数据库(使用内存中的德比).我在测试dao update方法时遇到问题,因为它修改数据然后另一个测试失败.因为我们所有人都知道测试应该独立于任何其他测试,并且我知道DBUnit在每次测试后都有一些清理和重新生成数据库的工具.但它不起作用!

代码就是这个(TestNG):

@BeforeMethod
public void prepareData() throws Exception {
  cleanAndPopulate("users");
}

public void cleanAndPopulate (String nameXML) throws Exception {
  IDatabaseConnection conn; 
  conn = new DatabaseConnection (sessionForTesting.connection());        
  InputStream is = DBconnection.class.getClassLoader()
    .getResourceAsStream(nameXML + ".xml");      
  dataset = new FlatXmlDataSet(is);
  System.out.println("*** Preparando base de datos de test"); 
  DatabaseOperation.CLEAN_INSERT.execute(conn, dataset); 
}
Run Code Online (Sandbox Code Playgroud)

这是测试(禁用以避免附带影响):

@Test(enabled=false) // Deja la BBDD en estado erroneo!!!
public void busco_y_actualizo() throws Exception { 
    PacoUser resultado = userdao.getById(1L);
    resultado.setName("OTRO");
    userdao.update(resultado);
    PacoUser resultado2 = userdao.getById(1L);
    AssertJUnit.assertNotNull(resultado2); 
    AssertJUnit.assertEquals("OTRO", resultado2.getName());    
}
Run Code Online (Sandbox Code Playgroud)

java tdd testng dbunit

7
推荐指数
2
解决办法
6519
查看次数

Hibernate Search不会索引/重新索引实体

我正在尝试在我的项目中使用Hibernate Search(现在使用junit + dbunit编写测试),但搜索查询不会返回任何结果.我昨天研究了这个问题并得出结论,问题是Hibernate Search与dbunit @DatabaseSetup不兼容(类似于这个未回答的问题中的类似问题:链接).我将提供更多细节,但首先是冷杉,有我的实体类:

@Entity
@Indexed
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "userId")
    private Long id;
    (...)
    @Column(nullable = false, unique = true)
    @Field(index = Index.YES, analyze=Analyze.YES, store=Store.NO)
    private String email;
    (...)
    @Column(nullable = false, unique = true)
    @Field(index = Index.YES, analyze=Analyze.YES, store=Store.NO)
    private String username;
    (...)
}
Run Code Online (Sandbox Code Playgroud)

我通过我的DAO将它保存到db:

@Repository
public class UserDAOImpl implements UserDAO {

    @Autowired
    private SessionFactory sessionFactory;

    @Override
    public long save(User toSave) {

        return (Long) this.sessionFactory.getCurrentSession().save(toSave);
    }
(...)
} …
Run Code Online (Sandbox Code Playgroud)

java spring dbunit hibernate hibernate-search

7
推荐指数
1
解决办法
2668
查看次数

DBUnit PostgresqlDataTypeFactory无法识别枚举列表

我正在使用DBUnit进行集成测试,在执行测试代码之前,我遇到了这个错误:

badges.track_types data type (2003, '_text') not recognized and will be ignored. See FAQ for more information.

org.dbunit.dataset.NoSuchColumnException: badges.TRACK_TYPES -  (Non-uppercase input column: track_types) in ColumnNameToIndexes cache map. Note that the map's column names are NOT case sensitive.
Run Code Online (Sandbox Code Playgroud)

被忽略的列是枚举列表.在数据集中,它是这样编写的:

<?xml version='1.0' encoding='UTF-8'?>
<dataset>
  // More info ...
  <badges name="30&apos;000" description="30k a day" image_name="30000.png" threshold_val="30000.00000000" has_many="true" id="45" track_types="{TRACK_GENERIC}" "/> 
</dataset> 
Run Code Online (Sandbox Code Playgroud)

我查看了DBUnit FAQ并看到了这个问题,说我必须覆盖isEnumType()方法来支持我的枚举是Postgresql,所以我这样做了:

/**
 * Override method to set custom properties/features
 */
protected void setUpDatabaseConfig(DatabaseConfig config) {

    config.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new PostgresqlDataTypeFactory(){ …
Run Code Online (Sandbox Code Playgroud)

java postgresql enums dbunit integration-testing

7
推荐指数
1
解决办法
819
查看次数

更改数据库模式和单元测试

     在我们开始之前,我知道很少有人认为测试数据库不是"单元测试".也许"集成测试"会是一个更好的名称.无论哪种方式,开发人员测试都会遇到数据库

     为了启用单元测试,我有一个开发人员本地数据库,我清除并在每次测试开始时使用dbUnit填充一组已知的数据.这一切都运行良好,直到测试使用的表以某种方式更改,我必须手动更新所有XML数据集.这是一种痛苦.我认为其他人必须遇到同样的问题,并希望找到一个很好的解决方案.因此,对于需要填充数据库的测试,您使用了什么以及如何处理表定义更改?(虽然我使用Java,但我对使用不同技术的解决方案持开放态度.)

编辑: 澄清一点.我有一个人为的测试,如:

void testLoadRevision() {
    database.clear(); // Clears every table dbUnit knows about.
    database.load("load/trevision.xml", "load/tissue.xml");
    SomeDatabaseThingie subject = new SomeDatabaseThingie(databaseProvider);
    Revision actual = subject.load();
    assert(actual, expected);
}
Run Code Online (Sandbox Code Playgroud)

在那里我有两个表 - tRevision和tIssue.加载的修订版使用来自tIssue的少量数据.后来tIssue获得了一个新的领域,修改不关心.由于新字段"not null"且没有合理的默认值,因此测试将失败,因为tIssue.xml将无效.

通过这样的小改动,编辑tIssue并不困难.但是当XML文件的数量随着每个流开始出现时,它就变成了大量的工作.

干杯,
    mlk

java dbunit unit-testing

6
推荐指数
1
解决办法
2296
查看次数

让DbUnit使用Hibernate事务

我在尝试将Hibernate事务中的更改推送到数据库以使DbUnit在我的测试用例中正常工作时遇到问题.似乎DbUnit没有看到Hibernate所做的更改,因为它们还没有在事务结束时提交......而且我不确定如何重构我的测试用例以使其工作.

这是我过度简化的测试用例来证明我的问题: -

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
        "classpath:applicationContext-test.xml"
})
@TransactionConfiguration(transactionManager = "transactionManager")
@Transactional
public class SomeTest {
    @Autowired
    protected DataSource dataSource;

    @Autowired
    private SessionFactory sessionFactory;

    @Test
    public void testThis() throws Exception {
        Session session = sessionFactory.getCurrentSession();

        assertEquals("initial overlayType count", 4, session.createQuery("from OverlayType").list().size());

        //-----------
        // Imagine this block is an API call, ex: someService.save("AAA");
        // But for the sake of simplicity, I do it this way
        OverlayType overlayType = new OverlayType();
        overlayType.setName("AAA");
        session.save(overlayType);
        //-----------

        // flush has no effect here
        session.flush(); …
Run Code Online (Sandbox Code Playgroud)

java junit spring dbunit hibernate

6
推荐指数
1
解决办法
5919
查看次数

使用DBUnit在数据库中声明更新数据的好策略是什么?

下面是一些(过度)简化的代码示例来描述我的单元测试方法.

CompanyDataSet.xml

<dataset>
    <company company_key="100" company_name="OldName" />
</dataset>
Run Code Online (Sandbox Code Playgroud)

CompanyDaoTest.java

@Test
public void testUpdateCompany() {
  CompanyDao companyDao = new CompanyDao();
  IDatabaseConnection dbConn = createConnection();

  IDataSet dataSet = createDataSet("CompanyDataSet.xml");
  DatabaseOperation.CLEAN_INSERT.execute(dbConn, dataSet);

  companyDao.updateCompany(100, "NewName");

  // What is a good way to assert updated company data ?
}
Run Code Online (Sandbox Code Playgroud)

我提出了两种断言公司数据的方法.

创建另一个数据集xml作为预期数据集.

另一个XML

<dataset>
    <company company_key="100" company_name="NewName" />
</dataset>
Run Code Online (Sandbox Code Playgroud)

在Java中断言部分

IDataSet actual = dbConn.createDataSet(new String[]{"company"});
IDataSet expected = createDataSet("CompanyDataSet_expected.xml");

Assertion.assertEquals(expected, actual);
Run Code Online (Sandbox Code Playgroud)

只需通过DAO加载公司对象,然后比较属性.

你应该明白这个想法.


我的问题

第一种方法很容易编写,但我必须为每种不同的更新方法创建另一个XML文件.创建这么多数据集XML文件听起来不是一个好主意.

第二种方法很简单,但是,当存在不同的更新方法时,测试类将填充使用不同值声明不同属性的方法.如果加载方法有问题,很多测试都会破坏.

是否有一种断言数据的好方法?是否有可能避免我刚才描述的问题(或者它真的不重要)?

UPDATE

由于没有人回答这个问题,我决定接受我的回答.

java dbunit unit-testing

6
推荐指数
1
解决办法
3033
查看次数

FlatXmlDataSet空表(DBUnit)

是否可以验证数据库没有具有平坦xml结构的特定表的行?就像是:

<dataset>
   <TABLE/>
</dataset
Run Code Online (Sandbox Code Playgroud)

但这不起作用,因为我认为它只会验证"TABLE"是否存在.

我正在测试删除..

java dbunit integration-testing

6
推荐指数
1
解决办法
813
查看次数

DBUnit错误 - 缺少以下bean:[dbUnitDatabaseConnection,dataSource]

我正在尝试使用DBUnit,从不同的配置文件(不同的项目)加载多个数据库.

在我的Foo @Configuration文件中,我有以下bean:

@Bean(name="dataSourceFoo")
public DataSource dataSourceFoo() {
    BasicDataSource dataSource = new BasicDataSource();
    ...
    return dataSource;
}
Run Code Online (Sandbox Code Playgroud)

在我的Bar @Configuration文件中,我有以下bean:

@Bean(name="dataSourceBar")
public DataSource dataSourceBar() {
    BasicDataSource dataSource = new BasicDataSource();
    ...
    return dataSource;
}
Run Code Online (Sandbox Code Playgroud)

在第三个项目中,我的测试文件如下所示:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = ThirdProjectAppContextConfig.class)
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,
        DirtiesContextTestExecutionListener.class,
        TransactionalTestExecutionListener.class,
        DbUnitTestExecutionListener.class })
@DatabaseSetups({
        @DatabaseSetup(connection = "dataSourceFoo", value = "classpath:db/FooTest.xml"),
        @DatabaseSetup(connection = "dataSourceBar", value = "classpath:db/BarTest.xml") })
@TestPropertySource("/application.properties")
@DirtiesContext
@Transactional
public class FooBarTest {

    @Autowired
    private Service service;

    @Test
    public void test(){
        service.callFooBar();
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

当我运行测试时,它会抛出以下错误:

java.lang.IllegalStateException: Unable …
Run Code Online (Sandbox Code Playgroud)

java spring dbunit datasource

6
推荐指数
1
解决办法
2687
查看次数

DbUnit 和 JSON 列类型支持

我想知道使 DbUnit 与 MySQL 的 JSON(B) 类型列一起使用的最佳方法是什么?我们确实到处都有这样的列,每当我尝试通过 XML 文件提供测试数据时,@DatabaseSetup我都会收到 NoSuchColumnException,这会阻止我对处理 JSON 的实体或存储库进行任何合理的集成测试:

org.dbunit.dataset.NoSuchColumnException: assistant_event.AEV_CONTEXT -  (Non-uppercase input column: aev_context) in ColumnNameToIndexes cache map. Note that the map's column names are NOT case sensitive.
Run Code Online (Sandbox Code Playgroud)

我知道这是因为我的AEV_CONTEXT列没有被识别,因为它是一个 JSON 列:

@Type(type = "json")
@Column(name = "aev_context", columnDefinition = "json")
private Context context;
Run Code Online (Sandbox Code Playgroud)

然而,我在尝试解决这个问题时遇到了困难。而且,更奇怪的是,我在这里也找不到这样的解决方法!事实上,我不知道那是属于 Hibernate 还是 DbUnit。

到目前为止真的只有我遇到这个问题吗?任何建议将不胜感激!

哦,如果您想知道,这就是我如何获得 Hibernate 的 JSON 支持:

https://vladmihalcea.com/how-to-map-json-objects-using-generic-hibernate-types/

java mysql testing dbunit spring-test-dbunit

6
推荐指数
1
解决办法
2825
查看次数