【问题标题】:Reset mysql database before running a JUnit test在运行 JUnit 测试之前重置 mysql 数据库
【发布时间】:2012-01-17 08:02:41
【问题描述】:

我有大约 10 个 JUnit 将自动执行。我想在每个人中重置数据库。我有这段代码:

//@Transactional
public class TestMediaObjectService extends AbstractDataAccessTest{

//This method reset the database, emptying the tables
    @Test
    public void testCreateDataBase() throws Exception {
        TestDatabaseCreation creation = new TestDatabaseCreation();
        creation.resetDatabase();
    }

//This is one of the methods. 
    @Test
    public void testStoreMediaObject() throws Exception {
//......
}

当我使用我在方法testCreateDataBase 中使用的相同脚本手动重置数据库,然后运行此测试(不使用该方法)时,会自动创建表。但是,如果我按照上面粘贴的方式运行代码,则不会创建该表,因此会出现此错误:

原因:com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:表“one_table”不存在

在测试中运行其他方法之前,我怎样才能在 every 中运行该方法?注解@Transactional被移除了,但是错误依旧存在。

【问题讨论】:

    标签: mysql hibernate spring junit


    【解决方案1】:

    通常您不需要手动重置数据库,因为 JUNIT 在每次测试之前都会为您执行此操作。使用这些注释:

    @TransactionConfiguration(defaultRollback = true)
    @Transactional
    @RunWith(SpringJUnit4ClassRunner.class)
    

    Junit 将在运行后回滚测试中完成的所有事务。您所需要的只是一个现有的空数据库。如果你使用 hibernate 来管理你的实体,你甚至不需要有表。

    如果您想手动进行,请在设置方法中使用@Before 注释:

    @Before
    public void init() {
        createTables();
    }
    

    这将在每次测试之前运行。

    如果您想为一个类中的所有测试设置一次数据库表,请使用@BeforeClass。但通常这不是最佳实践,因为每个测试都应该独立于任何其他测试。

    【讨论】:

    • 此配置不会重置数据库。它说测试将在数据库事务中执行,并且事务不会被提交而是回滚。一切都将发生在实体管理器缓存或未提交的数据库事务中。简单的单元测试应该以这种方式工作。更复杂的集成测试不会。
    • 我明白你的意思,尽管问题并没有具体说明是否需要提交数据。但是:你为什么要在单元测试中实际将数据提交到数据库?我能想到的唯一原因是测试您的数据库连接或事务环境,或者您是否有分布式环境。除了对现有数据的集成测试,我认为不应在单元测试中完成,因为该测试不会是独立的。它应该自己设置所有必需的数据。
    • 谢谢,但这些注释不会重置数据库。我得到 DuplicateObjectException。我正在我的应用程序中进行一些测试,并且我有一个针对该问题的数据库。是不是应用程序本身要使用的数据库
    • @Blanca Hdez:“但是数据库没有用这些注释重置。我得到 DuplicateObjectException” .. 是的,这个注释不会重置数据库,而是阻止在测试中所做的更改被持久化(除非您在测试中打开一个新事务)。所以问题可能是你应该从一个空数据库开始。
    猜你喜欢
    • 1970-01-01
    • 2013-04-25
    • 1970-01-01
    • 2010-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-08
    • 1970-01-01
    相关资源
    最近更新 更多