如何在Hibernate+Spring+JUnit中测试事务回滚

KeL*_*TaR 6 java junit spring hibernate transactions

我正在尝试测试出现问题时回滚事务的机制。我读了很多类似的主题,但没有任何帮助我。这是我尝试的:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "file:src/main/webapp/WEB-INF/rest-servlet.xml" })
@Transactional
public class TagDaoImplTest extends DatabaseTestCase {

    private static final String FLAT_XML_DATASET = "FlatXmlDataSet.xml";

    @Autowired
    private TagDao tagDao;
    @Autowired
    private SessionFactory sessionFactory;

    @Before
    public void setUp() throws Exception {
        DatabaseOperation.REFRESH.execute(getConnection(), getDataSet());
    }

    @Test
    public void testAddWithRollback() throws Exception {
        addWithRollback("testTagToAdd"); //i suppouse that we tried to add, but somthing went wrong and transaction was rolled back
        final Tag testTagToAdd = tagDao.findByTag("testTagToAdd"); // so db must be without changes and i check this
        assertNull(testTagToAdd);
    }

    @Rollback(true) //i want this method to rollback after its work to imitate corrupted transaction
    private void addWithRollback(String tag) throws Exception {
        tagDao.add(new Tag(tag));
    }
}
Run Code Online (Sandbox Code Playgroud)

我的道看起来像这样:

@Repository("tagDao")
public class TagDaoImpl implements TagDao {

    @Override
    public void add(Tag tag) {
        final Session session = sessionFactory.getCurrentSession();
        session.persist(tag);
    }
}
Run Code Online (Sandbox Code Playgroud)

但我的测试失败了,因为它在数据库中找到了该标签(这意味着事务没有回滚)。我尝试了许多不同的事情,例如获取当前会话和事务并手动调用回滚,但没有任何反应。你能帮我么?

Ruf*_*ufi 1

首先,对我来说,尝试测试存储库层感觉有点奇怪。通常不应该有任何业务逻辑,因此这意味着您尝试测试已经测试了数百万次的 Hibernate 或 SQL,但这样做是没有意义的。

我建议用这样的方式注释你的方法:

@Transactional(rollbackFor=Exception.class) 
Run Code Online (Sandbox Code Playgroud)

并可能指定异常。然后在测试中,您以该方法抛出此异常的方式准备系统。因此应该回滚它并且不应更改任何数据。

此外,我想补充一点,此时实际加载 spring 上下文很可能与生产环境不同。因此,这是一个额外的观点,我想说这样做是没有意义的。至少在存储库层。