测试我的DAO和服务没有问题,但是当我测试INSERT
或UPDATE
时,我想回滚事务而不影响我的数据库。
我在我的服务中使用@Transactional
来管理交易。我想知道,是否有可能知道某个事务是否正常,但是回滚它以防止更改数据库?
这是我的测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:/META-INF/spring.cfg.xml")
@TransactionConfiguration(defaultRollback=true)
public class MyServiceTest extends AbstractJUnit38SpringContextTests {
@Autowired
private MyService myService;
@BeforeClass
public static void setUpClass() throws Exception {
}
@AfterClass
public static void tearDownClass() throws Exception {
}
@Test
public void testInsert(){
long id = myService.addPerson( "JUNIT" );
assertNotNull( id );
if( id < 1 ){
fail();
}
}
}
问题是此测试将失败,因为事务已回滚,但插入正常!
如果我删除@TransactionConfiguration(defaultRollback=true)
然后测试通过,但新记录将被插入数据库。
@Test
@Transactional
@Rollback(true)
public void testInsert(){
long id = myService.addPerson( "JUNIT" );
assertNotNull(id);
if( id < 1 ){
fail();
}
}
现在可以正确测试传递,但忽略回滚并将记录插入数据库。
很明显,我已经使用addPerson()
在myService中注释了@Transactional
方法。
为什么忽略回滚?
答案 0 :(得分:30)
您需要将事务边界扩展到测试方法的边界。您可以通过将测试方法(或整个测试类)注释为@Transactional
:
@Test
@Transactional
public void testInsert(){
long id=myService.addPerson("JUNIT");
assertNotNull(id);
if(id<1){
fail();
}
}
您还可以使用此方法确保在回滚之前正确写入数据:
@Autowired SessionFactory sf;
@Test
@Transactional
public void testInsert(){
myService.addPerson("JUNIT");
sf.getCurrentSession().flush();
sf.getCurrentSession().doWork( ... check database state ... );
}
答案 1 :(得分:2)
结帐
http://static.springsource.org/spring/docs/2.5.x/reference/testing.html
特别是第8.3.4节
Spring有一些测试类可以将每个测试包装在一个事务中,因此DB不会被更改。如果您愿意,也可以更改该功能。
编辑 - 根据您的更多信息,您可能需要查看
AbstractTransactionalJUnit38SpringContextTests at
答案 2 :(得分:1)
在课前使用以下注释:
@TransactionConfiguration(transactionManager = "txManager",defaultRollback = true)
@Transactional
此处txManager
是应用程序上下文的事务管理器。
此处txManager
是来自application context
的事务管理器的实例或bean ID。
<!-- Transaction Manager -->
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />
在setUp()
方法中添加代码,这将在测试开始时执行,最后一个代码应该放在最后执行的teatDown()
方法中。或者您也可以使用@Before
和@After
注释代替它。
答案 3 :(得分:0)
如果你的
myService.addPerson("JUNIT");
方法注释为@Transactional,你会得到一些不同的类型或错误试图解决这个问题。所以你最好只测试DAO方法。