我有一个修改了一些数据库内容的 spock/spring 测试,我想知道如何回滚该记录。
目前我执行原始 sql 语句,保存字段数据并在成功测试后恢复该数据。但我的猜测是这可以通过更简单的方式完成吗?
@ContextConfiguration(locations = "classpath*:applicationContext-test.xml")
class RepositoryTest extends Specification {
@Shared sql = Sql.newInstance("jdbc:sqlserver://...")
ResourceRepository resourceRepository;
def "Save test"() {
setup:
// copy the row before we do changes! we need to restore this later on!
def row = sql.firstRow("select id, content, status from table-name where id = 12345")
when:
...
then:
..
cleanup:
sql.execute("""
update table-name set content = ${row.content}, status = ${row.status}
where id = ${row.id}
""")
}
}
最佳答案
我发现最好的方法是:
- 开始测试
- 开始交易
- (可选)使用类似 DBUnit 的东西加载测试需要的任何数据库数据
- 运行测试
- 回滚事务
请注意,所有数据库操作都发生在同一个事务中。因为此事务在测试结束时回滚(即使抛出异常),所以数据库在测试结束时应始终处于与开始时相同的状态。
Spring 提供了一些非常有用的类,它们将负责为每个测试启动和回滚事务。如果您使用的是 Spring 和 JUnit4,并且不介意您的测试类必须扩展 Spring 类,那么最简单的选择可能是扩展 AbstractTransactionalJUnit4SpringContextTests
// Location of the Spring config file(s)
@ContextConfiguration(locations = {"/application-context-test.xml", "classpath*:/application-context-persistence-test.xml"})
// Transaction manager bean name
@TransactionConfiguration(transactionManager = "hsqlTransactionManager", defaultRollback = true)
@Transactional(propagation=Propagation.REQUIRES_NEW)
public class MyTransactionalTests extends AbstractTransactionalJUnit4SpringContextTests {
@Test
public void thisWillRunInATransactionThatIsAutomaticallyRolledBack() {}
}
如果您不想扩展一个 Spring 类,您可以配置一个测试运行器而不是使用注释。 Spring 还支持许多其他主要的单元测试框架和旧版本的 JUnit。
关于testing - 如何在测试后回滚特定记录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6536216/