Другой JUnit-результат, начинающийся с теста Eclipse против mvn - PullRequest
1 голос
/ 01 октября 2009

У меня есть JUnit-тест, который успешно запускается при запуске mvn test, но не запускается при запуске из Eclipse (см. Трассировку стека ниже). Я пытаюсь вставить новые элементы в базу данных с помощью entityManager.persist () и entityManager.flush () (при вызове 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. При запуске приложения оно работает; он действительно дает сбой только при запуске JUnit-Test с включенным hibernate.hbm2ddl.auto = create.

В моем тестовом классе есть метод настройки, который выглядит следующим образом:

  @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.

Есть идеи?

Большое спасибо,

Stefan

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

Edit:

Я забыл: нет ошибки при запуске, но при неудачном методе теста в журнале появляется следующее предупреждение:

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]

Ответы [ 4 ]

2 голосов
/ 01 октября 2009

На основании SQLIntegrityConstraintViolationException похоже, что ваши операторы удаления не выполняются, возможно, у вас есть два файла delete.sql или у вас нет настроенного src / test / resources в качестве исходного местоположения в Eclipse?

При вызове applicationContext.getResource("delete.sql") ожидается поиск delete.sql в выходном каталоге. В сборке Maven содержимое src / test / resources будет скопировано в target / test-classes, это будет сделано только в сборке Eclipse, если определено местоположение источника.

true в конце первого вызова executeSqlScript означает, что процесс будет продолжен без выдачи исключения в случае ошибки, поэтому возможно, что ресурс не найден, а оператор удаления не выполнен , Если вы запустите сборку с параметром, установленным в false (и существующее содержимое), произойдет ли сбой?

Обратите внимание, что вы можете настроить файл Eclipse .classpath для вывода содержимого теста в target / test-classes, чтобы избежать конфликтов.

Шаги для этого:

  1. Открыть свойства проекта ( alt-enter )
    • Выбрать Путь сборки Java
    • Выберите вкладку Источник
    • Нажмите Разрешить выходные папки для исходных папок . Это добавляет новую запись в дерево исходных папок.
    • Развернуть дерево исходных папок.
    • Дважды щелкните папку вывода : запись.
    • Диалог спросит вас, хотите ли вы использовать выходную папку проекта по умолчанию или определенную выходную папку. Выберите второй вариант и нажмите Просмотр ...
    • Выберите нужную папку, нажмите ОК, а затем Готово.

В файле .classpath должны появиться следующие записи:

<classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
<classpathentry kind="src" output="target/test-classes" path="src/test/resources"/>
0 голосов
/ 05 февраля 2016

Это происходило со мной месяцами, и я в конце концов понял, что тестируемый код не был вполне настолько детерминированным, как я думал:

  1. Мой код мог возвращать неправильные данные, если его входные данные были в другом порядке
  2. Код перебирал набор, а не список.

Таким образом, в любом конкретном сеансе JVM из Eclipse и Maven обычно упорядочивают набор согласованным образом, но не всегда совпадают друг с другом.

0 голосов
/ 01 октября 2009

Мои замечания / вопрос:

  • при удалении строки "hibernate.hbm2ddl.auto" - действие по умолчанию none
  • какой базовый тестовый класс вы используете? Попробуйте расширяет класс org.springframework.test.jpa.AbstractJpaTests - он выполняет откат после каждого метода
  • из трассировки стека исключений кажется таблицы не чистые перед вставками
  • где хранится ваша база данных (файл)? Может быть, maven создаст чистый файл базы данных.
  • используете ли вы какие-либо плагины maven, которые запускаются в maven, а не в eclipse (например, hibernate3-maven-plugin)?

EDIT: По моему мнению, тест должен выполняться в чистой базе данных и оставлять базу данных чистой, поэтому каждый тест / метод должен выполнять откат после выполнения. Посмотрите на мой вопрос и ответы. Я думаю, что использовать hibernate3-maven-plugin необязательно.

0 голосов
/ 01 октября 2009

Что я заметил, что иногда результаты моего модульного теста меняются в зависимости от уровня песочницы, выполняемой используемым инструментом тестирования. Например, Eclipse, кажется, помещает текущий выбор песочницы ( класс, пакет, проект ) в один цикл setup-test-teardown в том же контексте, в то время как наш CI, кажется, помещает в песочницу каждый отдельный модульный тест как цикл setup-test-teardown.

Это означает, что если у вашего test1 есть побочный эффект, который затем используется в test2, он может работать в Eclipse, но также может не работать в других местах. В этом случае вам необходимо хотя бы частично переписать свои модульные тесты, чтобы отделить их друг от друга.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...