【问题标题】:Same hibernate session between JUnit tests causing problemsJUnit 测试之间的相同休眠会话导致问题
【发布时间】:2012-07-26 11:17:12
【问题描述】:

我正在开发一个基于 Spring 2.5 和 hibernate 3 的 Web 应用程序。最近我介绍了 JUnit 测试,并使用 DBUnit 框架完成了一些集成测试。 DBUnit 应该在一个测试和另一个测试之间使用 xml 数据集更新数据库,并且它运行良好,正如我所见。

但是,当我在测试中更新一个元素时,hibernate 似乎会捕获此信息,即使我在以下测试中加载该元素,该信息也是我修改过的信息。如果我在执行暂停时查看数据库,则 DBUnit 正确重置了数据库。所以我认为这可能是一个休眠问题..

有没有办法在测试之间进行拆解,说我想为我的 spring 上下文创建一个新的休眠会话?顺便说一句,我没有使用 Spring 注释,而是通过代码获取 Spring 上下文:

String[] contextLocations = new String[2];
contextLocations[0] = "WebContent/WEB-INF/applicationContext.xml";
contextLocations[1] = "src/System_V3/test/applicationContext.xml";
context = new FileSystemXmlApplicationContext(contextLocations);

DBUnit 设置:

@Before
public void setUpBeforeClass() throws Exception {
    handleSetUpOperation();
}

private static void handleSetUpOperation() throws Exception {
    conn = getConnection();
    conn.getConnection().setAutoCommit(false);
    final IDataSet data = getDataSet();
    try {
        DatabaseOperation.REFRESH.execute(conn, data);
    } finally {
        conn.close();
    }
}

private static IDatabaseConnection getConnection() throws ClassNotFoundException, SQLException,
        DatabaseUnitException {
    Class.forName("org.gjt.mm.mysql.Driver");
    return new DatabaseConnection(DriverManager.getConnection(
            "jdbc:mysql://localhost:3306/web_database", "root", "pass"));
}

private static IDataSet getDataSet() throws IOException, DataSetException {
    ClassLoader classLoader = TestPrueba.class.getClassLoader();
    return new FlatXmlDataSetBuilder().build(classLoader
            .getResourceAsStream("System_V3/test/dataset.xml"));
}

在 JUnit 4 中仅使用 @Test 注释完成测试,并且测试类不扩展任何库类。

有什么建议吗?

【问题讨论】:

  • 当您使用 @Before 注释 setupBeforeClass 方法时:您知道 @Before@BeforeClass JUnit4 注释之间的区别吗?
  • @Korgen,这个 setUpBeforeClass() 方法在执行每个测试之前调用 DBUnit 将 dataSet 数据插入数据库。是的,我想要这样。

标签: java spring hibernate junit4 dbunit


【解决方案1】:

不确定这是否对您有帮助 - 但以防万一......

尝试使用 session.clear() 并在拆卸方法中使用它。 请看这里http://docs.jboss.org/hibernate/orm/3.5/api/org/hibernate/Session.html#clear()

根据规范 session.clear() -> 彻底清除会话。驱逐所有加载的实例并取消所有挂起的保存、更新和删除。不要关闭打开的迭代器或 ScrollableResults 的实例。

【讨论】:

    【解决方案2】:

    您需要在事务中执行测试。这可以通过为您的测试设置SpringJUnit4ClassRunner 来实现。配置完成后,您可以在每个测试中使用 @Transactional 注释。

    通过这种方法,您也可以@Autowired 您的 bean 直接进行测试。

    例如:

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = { "classpath:context-file.xml" })
    public class MyTest {
    
        @Autowired
        private MyService myService;
    
        @Transactional
        @Test
        private void myFirstTest() {
            ...
            myService.executeSomething();
            ...
        }
    
    }
    

    当然,您可以在测试类上将默认行为设置为 RollBack,并使用 @TransactionConfiguration(defaultRollback = true/false) 对其进行注释

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-06
      • 2017-11-19
      • 1970-01-01
      • 2014-04-23
      • 1970-01-01
      相关资源
      最近更新 更多