【问题标题】:Different JUnit-result starting from Eclipse vs. mvn test从 Eclipse 与 mvn 测试开始的不同 JUnit 结果
【发布时间】:2010-12-02 21:28:42
【问题描述】:

我有一个 JUnit 测试,它在使用 mvn test 启动时成功,但在从 Eclipse 启动时失败(参见下面的堆栈跟踪)。我正在尝试使用 entityManager.persist() 和 entityManager.flush() 将新元素插入到数据库中(调用刷新时出现错误)。

我的 config.properties 如下所示:

db.url=jdbc:derby:target/testdb;create=true;territory=en_US;collation=TERRITORY_BASED
db.username=
db.password=

# Hibernate
hibernate.show_sql=true
hibernate.hbm2ddl.auto=create

使用该配置,我的测试在 Eclipse 中失败,但使用“mvn test”运行;如果我删除“hibernate.hbm2ddl.auto=create”行,则“mvn test”和 Eclipse 的测试都是成功的。运行应用程序时,它可以工作;只有在启用“hibernate.hbm2ddl.auto=create”的情况下运行 JUnit-Test 时才会失败。

在我的测试类中,有一个 setup-Method 看起来如下:

  @Before
  @Transactional(propagation = Propagation.REQUIRED, readOnly = false)
  public void setUpDatabase() {
    final Resource deleteScript = applicationContext.getResource("delete.sql");
    final Resource insertScript = applicationContext.getResource("insert.sql");
    SimpleJdbcTestUtils.executeSqlScript(simpleJdbcTemplate, deleteScript, true);
    SimpleJdbcTestUtils.executeSqlScript(simpleJdbcTemplate, insertScript, false);
  }

delete.sql 包含“delete from”语句,insert.sql 再次插入语句。

Java 版本 1.6.0_16,maven 2.1.0。

有什么想法吗?

非常感谢,

斯蒂芬

javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not insert: [ch.netcetera.gisab.masterdata.model.security.RuleTarget]
    at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:614)
    at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:307)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:198)
    at $Proxy47.flush(Unknown Source)
    at ch.netcetera.gisab.masterdata.dao.RuleDAOImpl.updateRuleTargetsOfRule(RuleDAOImpl.java:84)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
    at $Proxy72.updateRuleTargetsOfRule(Unknown Source)
    at ch.netcetera.gisab.masterdata.services.RoleServiceImpl.updateUserRoleTO(RoleServiceImpl.java:145)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
    at $Proxy74.updateUserRoleTO(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
    at org.springframework.aop.interceptor.CustomizableTraceInterceptor.invokeUnderTrace(CustomizableTraceInterceptor.java:255)
    at org.springframework.aop.interceptor.AbstractTraceInterceptor.invoke(AbstractTraceInterceptor.java:110)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
    at $Proxy74.updateUserRoleTO(Unknown Source)
    at ch.netcetera.gisab.masterdata.services.RoleServiceTest.testUpdateUserRoleTO(RoleServiceTest.java:140)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.test.context.junit4.SpringTestMethod.invoke(SpringTestMethod.java:160)
    at org.springframework.test.context.junit4.SpringMethodRoadie.runTestMethod(SpringMethodRoadie.java:233)
    at org.springframework.test.context.junit4.SpringMethodRoadie$RunBeforesThenTestThenAfters.run(SpringMethodRoadie.java:333)
    at org.springframework.test.context.junit4.SpringMethodRoadie.runWithRepetitions(SpringMethodRoadie.java:217)
    at org.springframework.test.context.junit4.SpringMethodRoadie.runTest(SpringMethodRoadie.java:197)
    at org.springframework.test.context.junit4.SpringMethodRoadie.run(SpringMethodRoadie.java:143)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.invokeTestMethod(SpringJUnit4ClassRunner.java:160)
    at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
    at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
    at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
    at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
    at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:97)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.hibernate.exception.ConstraintViolationException: could not insert: [ch.netcetera.gisab.masterdata.model.security.RuleTarget]
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:94)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2295)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2688)
    at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:79)
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:167)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027)
    at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:304)
    ... 66 more
Caused by: java.sql.SQLIntegrityConstraintViolationException: The statement was aborted because it would have caused a duplicate key value in a unique or primary key constraint or unique index identified by 'SQL091001075326220' defined on 'RULETARGET'.
    at org.apache.derby.impl.jdbc.SQLExceptionFactory40.getSQLException(Unknown Source)
    at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Unknown Source)
    at org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(Unknown Source)
    at org.apache.derby.impl.jdbc.TransactionResourceImpl.handleException(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedConnection.handleException(Unknown Source)
    at org.apache.derby.impl.jdbc.ConnectionChild.handleException(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeStatement(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeUpdate(Unknown Source)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:102)
    at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:46)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2275)
    ... 75 more
Caused by: java.sql.SQLException: The statement was aborted because it would have caused a duplicate key value in a unique or primary key constraint or unique index identified by 'SQL091001075326220' defined on 'RULETARGET'.
    at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source)
    at org.apache.derby.impl.jdbc.SQLExceptionFactory40.wrapArgsForTransportAcrossDRDA(Unknown Source)
    ... 87 more
Caused by: ERROR 23505: The statement was aborted because it would have caused a duplicate key value in a unique or primary key constraint or unique index identified by 'SQL091001075326220' defined on 'RULETARGET'.
    at org.apache.derby.iapi.error.StandardException.newException(Unknown Source)
    at org.apache.derby.impl.sql.execute.IndexChanger.insertAndCheckDups(Unknown Source)
    at org.apache.derby.impl.sql.execute.IndexChanger.doInsert(Unknown Source)
    at org.apache.derby.impl.sql.execute.IndexChanger.insert(Unknown Source)
    at org.apache.derby.impl.sql.execute.IndexSetChanger.insert(Unknown Source)
    at org.apache.derby.impl.sql.execute.RowChangerImpl.insertRow(Unknown Source)
    at org.apache.derby.impl.sql.execute.InsertResultSet.normalInsertCore(Unknown Source)
    at org.apache.derby.impl.sql.execute.InsertResultSet.open(Unknown Source)
    at org.apache.derby.impl.sql.GenericPreparedStatement.execute(Unknown Source)
    ... 81 more

编辑:

我忘记了:启动过程中没有错误,但是在失败的测试方法期间,我在日志中收到以下警告:

2009-10-01 10:16:38,924 | main            | WARN  | JDBCExceptionReporter          | SQL Warning: 10000, SQLState: 01J01
2009-10-01 10:16:38,924 | main            | WARN  | JDBCExceptionReporter          | Database 'target/testdb' not created, connection made to existing database instead.
Hibernate: insert into RuleTarget (ruleid, targetid, type, version, id) values (?, ?, ?, ?, ?)
2009-10-01 10:16:38,939 | main            | WARN  | JDBCExceptionReporter          | SQL Error: 20000, SQLState: 23505
2009-10-01 10:16:38,939 | main            | ERROR | JDBCExceptionReporter          | The statement was aborted because it would have caused a duplicate key value in a unique or primary key constraint or unique index identified by 'SQL091001101631840' defined on 'RULETARGET'.
2009-10-01 10:16:38,939 | main            | ERROR | AbstractFlushingEventListener  | Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: could not insert: [ch.netcetera.gisab.masterdata.model.security.RuleTarget]

【问题讨论】:

  • 在启动过程中执行脚本时是否崩溃?
  • 不...但是有一个警告我忘了提...(我已将其添加到原始帖子中)

标签: java eclipse maven-2 junit


【解决方案1】:

根据SQLIntegrityConstraintViolationException,您的删除语句似乎没有被执行,您是否有两个 delete.sql 文件或者没有将 src/test/resources 配置为 Eclipse 中的源位置?

applicationContext.getResource("delete.sql") 调用将期望在输出目录中找到 delete.sql。在 Maven 构建中,src/test/resources 的内容将被复制到 target/test-classes,如果源位置已定义,这只会在 Eclipse 构建中完成。

第一次executeSqlScript调用结束时的true表示如果发生错误,进程会继续进行,不会抛出异常,所以可能是找不到资源,delete语句没有执行.如果您在选项设置为 false(和现有内容)的情况下运行构建,它会失败吗?

请注意,您可以配置 Eclipse .classpath 文件以将测试内容输出到目标/测试类以避免冲突。

执行此操作的步骤是:

  1. 打开项目属性(alt-enter
    • 选择Java 构建路径
    • 选择来源标签
    • 点击允许源文件夹的输出文件夹。这会在源文件夹树中添加一个新条目。
    • 展开源文件夹树。
    • 双击输出文件夹:条目。
    • 一个对话框询问您是要使用项目的默认输出文件夹还是特定的输出文件夹。选择第二个选项并点击Browse...
    • 选择所需的文件夹并单击确定,然后单击完成。

您应该在.classpath 文件中得到以下条目:

<classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
<classpathentry kind="src" output="target/test-classes" path="src/test/resources"/>

【讨论】:

  • 非常感谢您提供的信息!我检查了 - 只有一个 delete.sql 文件,在调试时很明显它确实找到了。
  • 老兄!非常感谢!
【解决方案2】:

我注意到,有时我的单元测试输出会根据使用的测试工具完成的沙盒级别而变化。例如,Eclipse 似乎将当前选择(类、包、项目)沙箱到同一上下文中的单个 setup-test-teardown 循环中,而我们的 CI 似乎将每个单元测试作为 setup-test-teardown 循环进行沙盒测试。 p>

这意味着如果您的test1 有副作用,然后在test2 中使用,它可能在 Eclipse 中工作,但也可能失败别处。如果是这种情况,您需要至少部分重写单元测试以将它们彼此分离。

【讨论】:

  • 非常感谢您的回答...我想过这样的事情;但如果我只从 Eclipse 中运行该特定方法,它也不起作用......
【解决方案3】:

我的评论/问题:

  • 当您删除“hibernate.hbm2ddl.auto”行时 - 默认操作是无
  • 您使用什么基础测试类?尝试扩展类 org.springframework.test.jpa.AbstractJpaTests - 它会在每个方法之后回滚
  • 从异常堆栈跟踪看来,插入前表不干净
  • 您的数据库(文件)存储在哪里?也许 maven 构建干净的数据库文件。
  • 您是否使用在 maven 而不是在 eclipse 中运行的任何 maven 插件(如 hibernate3-maven-plugin)?

编辑: 在我看来,测试应该在干净的数据库中运行并保持数据库干净,所以每个测试/方法都应该在执行后回滚。查看my qestion 和回复。我认为使用 hibernate3-maven-plugin 是可选的。

【讨论】:

  • - 我的测试类扩展了 AbstractTransactionalJUnit4SpringContextTests - 数据库文件存储在本地; maven clean 没有帮助...... - 最有趣的是:是的,使用了 hibernate3-maven!
【解决方案4】:

这在我身上发生了几个月,我最终意识到被测试的代码并不像我想象的那样完全确定性:

  1. 如果输入顺序不同,我的代码很容易返回错误内容
  2. 代码正在迭代 Set,而不是 List。

因此,在任何给定的会话中,来自 Eclipse 和 Maven 的 JVM 通常会以一致的方式对集合进行排序,但并不总是彼此相同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-14
    • 2017-04-20
    • 2021-06-11
    • 2023-03-09
    • 2015-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多