在我的项目中,我使用了spring,jpa和PostgreSQL DB,我在DB中有很多表,我需要对所有这些表进行单元测试.
是否有任何框架在每次测试完成后回滚所有事务,因此每个测试都会有新的/相同的DB数据进行测试.这种方式在所有测试执行之后,DB模式的数据将保持原样.
有什么建议吗?
我对DBUnit有所了解,但是我需要为每个测试编写每个输入数据的.xml文件,需要在setup()中插入数据并清除/删除tearDown()中的数据,但似乎没有更好的策略对我来说.
任何建议表示赞赏.谢谢.
我有一个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) 我正在尝试在我的项目中使用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) 我正在使用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'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) 在我们开始之前,我知道很少有人认为测试数据库不是"单元测试".也许"集成测试"会是一个更好的名称.无论哪种方式,开发人员测试都会遇到数据库
为了启用单元测试,我有一个开发人员本地数据库,我清除并在每次测试开始时使用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
我在尝试将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) 下面是一些(过度)简化的代码示例来描述我的单元测试方法.
<dataset>
<company company_key="100" company_name="OldName" />
</dataset>
Run Code Online (Sandbox Code Playgroud)
@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文件听起来不是一个好主意.
第二种方法很简单,但是,当存在不同的更新方法时,测试类将填充使用不同值声明不同属性的方法.如果加载方法有问题,很多测试都会破坏.
是否有一种断言数据的好方法?是否有可能避免我刚才描述的问题(或者它真的不重要)?
由于没有人回答这个问题,我决定接受我的回答.
是否可以验证数据库没有具有平坦xml结构的特定表的行?就像是:
<dataset>
<TABLE/>
</dataset
Run Code Online (Sandbox Code Playgroud)
但这不起作用,因为我认为它只会验证"TABLE"是否存在.
我正在测试删除..
我正在尝试使用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) 我想知道使 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/
dbunit ×10
java ×10
spring ×4
unit-testing ×3
hibernate ×2
datasource ×1
enums ×1
jpa ×1
junit ×1
mysql ×1
postgresql ×1
tdd ×1
testing ×1
testng ×1