我想使用SpringContextTests测试我的Dao类
在我的方法类中,我扩展了AbstractTransactionalJUnit4SpringContextTests
,以便我的测试类与JUnit4集成。我还设置了配置,并在@Before
中的@After
和tearDown中清理初始化和数据库。我的测试类很完美。
我的问题是,当我运行我的测试类并且数据库充满了数据时,原始数据没有回滚,我的数据库被清除。在@Before
方法中,我清除数据库并填充数据,认为我将能够回滚它,但事实并非如此。
任何人都可以找到一个可以在数据库中工作和回滚信息的示例。
ADDONS:
我的测试方法中的每个数据库操作都会被回滚。但是super.deleteFromTables("person")
方法中@Before
的执行没有从数据库中回滚所有以前的数据。
Spring回滚所有CRUD操作,但在事务不回滚之前清理数据库。
答案 0 :(得分:2)
感谢所有回答我问题的人。我从那些答案中学到了很多东西,但它并没有解决我的问题
我知道我的测试数据可以进行事务管理,并且可以正常工作
这个错误就在我身上
我忘记了有关数据库命令的教训,当您在DML语句之后执行DDL语句时,它将自动提交事务。我在DML之后执行了一个DDL,删除了所有记录,然后ALTER
表的AUTO_INCREMENT
,其中的{{1}}将导致自动提交并永久删除表的所有记录。
固定情景解决了我的问题。
答案 1 :(得分:1)
可能的原因:
至于一个例子,这是一个(我的头脑,未编译)
public class DBTest extends AbstractTransactionalJUnit4SpringContextTests {
@Autowired
private SomeDAO _aBeanDefinedInMyContextFile;
@Test
public void insert_works() {
assert _aBeanDefinedInMyContextFile.findAll() == 0;
_aBeanDefinedInMyContextFile.save(new Bean());
assert _aBeanDefinedInMyContextFile.findAll() == 1;
}
}
关键点:
SomeDAO
是一个接口,对应于在我的上下文中声明的bean; 答案 2 :(得分:1)
我不确定你班上有什么问题。以下是使用dbunit和spring 2.5执行所需操作的类的摘录:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={
"testContext.xml"})
@TransactionConfiguration
@Transactional
public class SampleDAOTest {
@Autowired
private DataSource dataSource;
@Autowired
private SampleDAO sampleDAO;
@Before
public void onSetUpInTransaction() throws Exception {
//Populate Test data
IDatabaseConnection dbUnitCon = new DatabaseConnection(DataSourceUtils.getConnection(dataSource), "DATASOURCE");
//read in from a dbunit excel file of test data
IDataSet dataSet = new XlsDataSet(new File("src/test/resources/TestData.xls"));
DatabaseOperation.INSERT.execute(dbUnitCon, dataSet);
}
@Test
public void testGetIntermediaryOrganisation() {
// Test getting a user
User object = sampleDAO.getUser(99L);
assertTrue(object.getValue);
}
}
此方法的一个优点是您不需要扩展任何类。因此,您仍然可以拥有自己的测试层次结构。
如果你真的想坚持使用当前的方法,而不是使用@before注释我瘦,你需要覆盖下面的方法并将你的设置代码放在那里。
@Override
public void onSetUpInTransaction() throws Exception {...}
希望这有帮助
答案 3 :(得分:0)
对于您的问题,我建议您使用单独的数据库实例来运行您的测试。这样,您可以安全地擦除它并让测试根据需要进行初始化。
据我所知,数据库测试的Spring支持类只回滚测试中发生的事情,而不是在测试的设置和拆卸中发生的事情。
答案 4 :(得分:0)
同意Confusion--您应该针对自己的数据库架构运行测试。
有了这个,你可以将你的休眠属性设置为'create-drop':
使用create-drop,数据库架构 将被删除时 SessionFactory显式关闭。
请参阅:Optional Hibernate Config properites
示例摘录:
<bean id="sessionBean" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">create-drop</prop>
...etc
答案 5 :(得分:0)
虽然我同意这个人建议使用decored db进行测试,但没有任何理由说使用填充的db不起作用,@ Before和@After方法都在事务上下文中执行,因此应该回滚更改。
候选条件:
你可以发布@Before方法,我只是想知道你是在清理表还是实际丢弃并重新创建它们?
答案 6 :(得分:0)
据我所知,通过查看AbstractJUnit4SpringContextTests和TransactionalTestExecutionListener的Javadocs和源代码,您需要注释要使用@Transactional进行事务处理的测试方法。
还有@BeforeTransaction和@AfterTransaction注释,您可以更好地控制事务中的运行。
我建议您创建使用所有这些注释注释的方法,包括@Before,然后在这些方法中使用断点运行测试。通过这种方式,您可以查看堆栈并确定spring是否已为您启动了事务。如果您在堆栈中看到类似“TransactionInterceptor”的内容,或者名称中包含“Transaction”的任何内容,那么您很可能正在进行交易。
答案 7 :(得分:0)
您在@Before方法中执行super.deleteFromTables,该方法位于tx内。那么如果tx被回滚,那么删除也不会被回滚吗?