Как настроить JPA для тестирования в Знатоке

Вам не нужно второе правило перезаписи.

Ваш CSS существует здесь: /css/normalize.css

Ваша страница просматривает здесь: / swift-details /2/abblinbb/css/normalize.css

Все, что вам нужно, это «передние косые черты» перед вашими дорожками CSS / JS.

67
задан Peter Becker 22 December 2008 в 04:58
поделиться

8 ответов

Сохраните две копии файла persistence.xml. Один для тестирования и другого для нормальной сборки.

копия жизненного цикла по умолчанию сборка persistence.xml к src/test/resources/META-INF

Создает отдельный профиль который, когда выполненный скопирует тестирование persistence.xml в src/test/resources/META-INF

3
ответ дан TRF 7 November 2019 в 10:48
поделиться

Кажется, что несколько файлов persistence.xml являются общей проблемой с JPA, решенным только приемами classloading.

обходное решение А, которое работает на меня, должно определить несколько единиц персистентности в одном файле persistence.xml и затем удостовериться, что Ваше развертывание и тестовый код используют различную привязку (в Spring, можно установить "persistenceUnitName" свойство на фабрике менеджера по объекту). Это загрязняет Ваш файл развертывания тестовой конфигурацией, но если Вы не возражаете против этого, это работает хорошо.

13
ответ дан Peter Becker 7 November 2019 в 10:48
поделиться

Persistence.xml используется в качестве отправной точки для поиска классов сущностей, если вы не перечислите все классы явно и не добавите. Поэтому, если вы хотите заменить этот файл другим, скажем, из src / test / resources, вы должны указать каждый отдельный класс сущности во втором файле persistence.xml, иначе класс сущности не будет найден.

Другим решением было бы перезапишите файл, используя maven-resources-plugin (цель «копировать ресурсы»). Но тогда вам придется перезаписать его дважды: один раз для тестирования (например, этапы тестовых классов процесса) и один раз для реальной упаковки (этап подготовки пакета).

3
ответ дан 24 November 2019 в 14:42
поделиться

Я пытаюсь сделать то же самое. У меня есть решение, которое мне подходит - ваше может отличаться (и вам может не понравиться решение ... оно немного низкоуровневое).

Я наткнулся на статью в сети, где они использовали пользовательский загрузчик классов сделать нечто подобное, что послужило вдохновением. Если кто-то может увидеть, как улучшить, то предложения будут приветствоваться, кстати. Для развертывания я полагаюсь на контейнерную инъекцию EntityManager, но для тестирования я сам создаю его, используя этот код:

final Thread currentThread = Thread.currentThread();
final ClassLoader saveClassLoader = currentThread.getContextClassLoader();
currentThread.setContextClassLoader(new ClassLoaderProxy(saveClassLoader));

EntityManagerFactory emFactory = Persistence.createEntityManagerFactory("test");
em = emFactory.createEntityManager();

Тогда ClassLoaderProxy настолько минимален, насколько это возможно, и просто перенаправляет запросы для META-INF / persistence.xml в META- INF / test-persist.xml:

public class ClassLoaderProxy extends ClassLoader {

    public ClassLoaderProxy(final ClassLoader parent) {
        super();
    }

    @Override
    public Enumeration<URL> getResources(final String name) throws IOException {
        if (!"META-INF/persistence.xml".equals(name)) {
            return super.getResources(name);
        } else {
            System.out.println("Redirecting persistence.xml to test-persist.xml");
            return super.getResources("META-INF/test-persist.xml");
        }
    }
}

Чтобы объяснить это немного подробнее:

  1. Есть два файла persistence.xml (один с именем persistence. xml, который используется вне тестирования, и один с именем test-persist.xml, который используется для тестов).
  2. Пользовательский загрузчик классов только активен для модульных тестов (для развертывания все нормально)
  3. Загрузчик настраиваемых классов перенаправляет запросы на «META-INF / persistence.xml» в тестовую версию («META-INF / test-persist.xml»).

Изначально я столкнулся с некоторыми проблемами, потому что Hibernate вернется (каким-то образом) к загрузчику классов, который использовался для загрузки Hibernate (по крайней мере, я думаю, что это то, что происходило). Я обнаружил, что помещая код переключения ClassLoader (первый блок) в качестве статического блока в вашем тестовом случае, он будет загружен до Hibernate, но, в зависимости от вашей структуры модульного теста, вам также может потребоваться поместить тот же код в другие места (фу)

xml, который используется для тестов).
  • Пользовательский загрузчик классов только активен для модульных тестов (для развертывания все нормально)
  • Пользовательский загрузчик классов перенаправляет запросы на "META-INF / persistence .xml "в тестовую версию (" META-INF / test-persist.xml ").
  • Изначально я столкнулся с некоторыми проблемами, потому что Hibernate вернется (каким-то образом) к загрузчику классов, который использовался для загрузки Hibernate (по крайней мере, я думаю, что это то, что происходило). Я обнаружил, что помещая код переключения ClassLoader (первый блок) в качестве статического блока в вашем тестовом случае, он будет загружен до Hibernate, но, в зависимости от вашей структуры модульного теста, вам также может потребоваться поместить тот же код в другие места (фу)

    xml, который используется для тестов).
  • Пользовательский загрузчик классов только активен для модульных тестов (для развертывания все нормально)
  • Пользовательский загрузчик классов перенаправляет запросы на "META-INF / persistence .xml "в тестовую версию (" META-INF / test-persist.xml ").
  • Изначально я столкнулся с некоторыми проблемами, потому что Hibernate вернется (каким-то образом) к загрузчику классов, который использовался для загрузки Hibernate (по крайней мере, я думаю, что это то, что происходило). Я обнаружил, что помещая код переключения ClassLoader (первый блок) в качестве статического блока в вашем тестовом случае, он будет загружен до Hibernate, но, в зависимости от вашей структуры модульного теста, вам также может потребоваться поместить тот же код в другие места (фу)

  • Пользовательский загрузчик классов только активен для модульных тестов (для развертывания все в норме)
  • Пользовательский загрузчик классов перенаправляет запросы на "META-INF / persistence.xml" в тестовую версию ( «META-INF / test-persist.xml»).
  • Изначально я столкнулся с некоторыми проблемами, потому что Hibernate вернется (каким-то образом) к загрузчику классов, который использовался для загрузки Hibernate (по крайней мере, я думаю, что это то, что происходило). Я обнаружил, что помещая код переключения ClassLoader (первый блок) в качестве статического блока в вашем тестовом случае, он будет загружен до Hibernate, но, в зависимости от вашей структуры модульного теста, вам также может потребоваться поместить тот же код в другие места (фу)

  • Пользовательский загрузчик классов только активен для модульных тестов (для развертывания все в норме)
  • Пользовательский загрузчик классов перенаправляет запросы на "META-INF / persistence.xml" в тестовую версию ( «META-INF / test-persist.xml»).
  • Изначально я столкнулся с некоторыми проблемами, потому что Hibernate вернется (каким-то образом) к загрузчику классов, который использовался для загрузки Hibernate (по крайней мере, я думаю, что это то, что происходило). Я обнаружил, что помещая код переключения ClassLoader (первый блок) в качестве статического блока в вашем тестовом случае, он будет загружен до Hibernate, но, в зависимости от вашей структуры модульного теста, вам также может потребоваться поместить тот же код в другие места (фу)

    к тестовой версии ("META-INF / test-persist.xml").

    Изначально я столкнулся с некоторыми проблемами, потому что Hibernate вернется (каким-то образом) к загрузчику классов, который использовался для загрузки Hibernate (по крайней мере, я думаю, что это то, что происходило). Я обнаружил, что помещая код переключения ClassLoader (первый блок) в качестве статического блока в вашем тестовом случае, он будет загружен до Hibernate, но, в зависимости от вашей структуры модульного теста, вам также может потребоваться поместить тот же код в другие места (фу)

    к тестовой версии ("META-INF / test-persist.xml").

    Изначально я столкнулся с некоторыми проблемами, потому что Hibernate вернется (каким-то образом) к загрузчику классов, который использовался для загрузки Hibernate (по крайней мере, я думаю, что это то, что происходило). Я обнаружил, что помещая код переключения ClassLoader (первый блок) в качестве статического блока в вашем тестовом случае, он будет загружен до Hibernate, но, в зависимости от вашей структуры модульного теста, вам также может потребоваться поместить тот же код в другие места (фу)

    1
    ответ дан 24 November 2019 в 14:42
    поделиться

    The following will work for Maven 2.1+ (prior to that there wasn't a phase between test and package that you could bind an execution to).

    You can use the maven-antrun-plugin to replace the persistence.xml with the test version for the duration of the tests, then restore the proper version before the project is packaged.

    This example assumes the production version is src/main/resources/META-INF/persistence.xml and the test version is src/test/resources/META-INF/persistence.xml, so they will be copied to target/classes/META-INF and target/test-classes/META-INF respectively.

    It would be more elegant to encapsulate this into a mojo, but as you're only copying a file, it seems like overkill.

    <plugin>
      <artifactId>maven-antrun-plugin</artifactId>
      <version>1.3</version>
      <executions>
        <execution>
          <id>copy-test-persistence</id>
          <phase>process-test-resources</phase>
          <configuration>
            <tasks>
              <!--backup the "proper" persistence.xml-->
              <copy file="${project.build.outputDirectory}/META-INF/persistence.xml" tofile="${project.build.outputDirectory}/META-INF/persistence.xml.proper"/>
              <!--replace the "proper" persistence.xml with the "test" version-->
              <copy file="${project.build.testOutputDirectory}/META-INF/persistence.xml" tofile="${project.build.outputDirectory}/META-INF/persistence.xml"/>
            </tasks>
          </configuration>
          <goals>
            <goal>run</goal>
          </goals>
        </execution>
        <execution>
          <id>restore-persistence</id>
          <phase>prepare-package</phase>
          <configuration>
            <tasks>
              <!--restore the "proper" persistence.xml-->
              <copy file="${project.build.outputDirectory}/META-INF/persistence.xml.proper" tofile="${project.build.outputDirectory}/META-INF/persistence.xml"/>
            </tasks>
          </configuration>
          <goals>
            <goal>run</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
    
    26
    ответ дан 24 November 2019 в 14:42
    поделиться

    поместил тесты в собственный проект maven с его persistence.xml

    0
    ответ дан 24 November 2019 в 14:42
    поделиться

    Я предпочитаю использовать другой файл persistence.xml для тестирования и производства в качестве сообщения Rich Seller (спасибо !!).

    Но нужно изменить:

    <copy file="${project.build.outputDirectory}/META-INF/persistence.xml.proper" tofile="${project.build.outputDirectory}/META-INF/persistence.xml"/>
    

    для:

    <move file="${project.build.outputDirectory}/META-INF/persistence.xml.proper" tofile="${project.build.outputDirectory}/META-INF/persistence.xml" overwrite="true"/>
    

    Чтобы файл persistence.xml.proper не был встроен в файл .jar

    5
    ответ дан 24 November 2019 в 14:42
    поделиться

    В проекте EE6/CDI/JPA тестовый src/test/resources/META-INF/persistence.xml прекрасно подхватывается без дополнительной настройки.

    При использовании JPA в Spring в контексте приложения, используемого для тестирования, работает следующее:

    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <!--
            JPA requires META-INF/persistence.xml, but somehow prefers the one
            in classes/META-INF over the one in test-classes/META-INF. Spring
            to the rescue, as it allows for setting things differently, like by
            referring to "classpath:persistence-TEST.xml". Or, simply referring
            to "META-INF/persistence.xml" makes JPA use the test version too: 
        -->
        <property name="persistenceXmlLocation" value="META-INF/persistence.xml" />
    
        <!-- As defined in /src/test/resources/META-INF/persistence.xml -->
        <property name="persistenceUnitName" value="myTestPersistenceUnit" />
        <property name="jpaVendorAdapter">
            <bean
                class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            </bean>
        </property>
    </bean>
    

    Здесь /src/test/resources/META-INF/persistence.xml (скопированный в target/test-classes) предпочтительнее, чем /src/main/resources/META-INF/persistence.xml (скопированный в target/classes).

    К сожалению, расположение файла persistence.xml также определяет так называемый "persistence unit's root", который затем определяет, какие классы сканируются на предмет @Entity аннотаций. Таким образом, использование /src/test/resources/META-INF/persistence.xml будет сканировать классы в target/test-classes, а не классы в target/classes (где находятся классы, которые нужно тестировать).

    Следовательно, для тестирования необходимо явно добавить записи в persistence.xml, чтобы избежать java.lang.IllegalArgumentException: Not an entity: class ... . Необходимости в можно избежать, если использовать другое имя файла, например persistence-TEST.xml, и поместить этот файл в ту же папку, что и обычный файл persistence.xml. Тогда контекст Spring из вашей тестовой папки сможет просто ссылаться на , и Spring найдет его для вас в src/main.

    В качестве альтернативы можно было бы сохранить persistence.xml одинаковым для реального приложения и тестов, и определить только один в src/main. Большинство настроек, таких как драйверы, диалект и необязательные учетные данные, могут быть выполнены в контексте Spring. Также такие настройки, как hibernate.hbm2ddl.auto могут быть переданы в контексте:

    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <!-- For example: com.mysql.jdbc.Driver or org.h2.Driver -->
        <property name="driverClassName" value="#{myConfig['db.driver']}" />
        <!-- For example: jdbc:mysql://localhost:3306/myDbName or 
            jdbc:h2:mem:test;DB_CLOSE_DELAY=-1 -->
        <property name="url" value="#{myConfig['db.url']}" />
        <!-- Ignored for H2 -->
        <property name="username" value="#{myConfig['db.username']}" />
        <property name="password" value="#{myConfig['db.password']}" />
    </bean>
    
    <bean id="jpaAdaptor"
        class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
        <!-- For example: org.hibernate.dialect.MySQL5Dialect or 
            org.hibernate.dialect.H2Dialect -->
        <property name="databasePlatform" value="#{myConfig['db.dialect']}" />
    </bean>
    
    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="jpaVendorAdapter" ref="jpaAdapter" />
        <property name="jpaProperties">
            <props>
                <!-- For example: validate, update, create or create-drop -->
                <prop key="hibernate.hbm2ddl.auto">#{myConfig['db.ddl']}</prop>
                <prop key="hibernate.show_sql">#{myConfig['db.showSql']}</prop>
                <prop key="hibernate.format_sql">true</prop>
            </props>
        </property>
    </bean>
    
    21
    ответ дан 24 November 2019 в 14:42
    поделиться
    Другие вопросы по тегам:

    Похожие вопросы: