[英]Spring Integration Testing environment not dispatching JPA entity lifecycle event
[英]integration testing with JPA and Spring
我有一個Spring / JPA Web應用程序,我想為其編寫一些測試。 理想情況下,我希望能夠:
我知道Spring提供了可以提供我正在尋找的事務行為的類。 理想情況下,最終解決方案應如下所示
// This dataset will be used for all tests that don't override it with their own annotation
@TestData('/dbunit/dataSetDefault.xml')
public class MyTests extends ProbablySomethingFromTheSpringFramework {
@Test
void testWithDefaultDataSet() {
// Transaction is implicitly started here
// My test code goes here
// A transaction is implicitly rolled-back here
}
@TestData('/dbunit/dataSetCustom.xml')
@Test
void testWithCustomDataSet() {
// Same as the other test
}
}
顯然,父類和@TestData
是虛構的,是否有可用的東西提供我想要的功能?
剩下的問題是如何創建測試數據庫模式。 理想情況下,這將在所有測試運行之前(由Maven執行)。 有人可以建議我如何實現這一目標嗎? 我想它涉及使用某種方法將JPA注釋轉換為DDL,然后使用其他方法將其加載到測試數據庫模式中。
謝謝!
理想情況下,我希望能夠:
- 在運行測試之前,一次創建測試數據庫模式(從帶有JPA注釋的類)
至少Hibernate使得可以從帶注釋的類創建數據庫,我想其他的JPA實現也可以使用。
- 在自己的事務中運行每個測試方法,該方法在測試完成時會回滾
參見@TransactionConfiguration和那里的defaultRollback -value以及AbstractTransactionalJUnit4SpringContextTests (至少在JUnit 3.8和TestNG中也有類似的抽象類),請仔細閱讀javadocs中的See also-節,它們指向許多非常有用的相關類和注釋。
- 在類或方法級別上指定要為每個測試加載的(DbUnit)數據集。 應在事務開始后加載測試數據,以便在測試完成時也回滾測試數據
我實際上從未使用過DbUnit,但至少使用JUnit,您可以使用@Before和@BeforeClass在每個測試和類之前分別運行方法(還有@After和@AfterClass)。 如果您具有類層次結構,則@ Before / @ BeforeClass注釋的方法將以擴展順序運行(首先是基類)。 有關運行sql腳本的信息,請參見例如SimpleJdbcTestUtils 。
- 將Spring bean注入測試類
AbstractTransactionalJUnit4SpringContextTests是ApplicationContextAware,另請參見@ContextConfiguration進行設置。
最后,這是我用來擴展實際集成測試的基類的一部分(如果重要的話,從Spring 3,JUnit4,Hibernate作為JPA提供者):
//test-context, same as normal context, except uses H2 for in-memory database and has some stuff for faking session- and request-scope
@ContextConfiguration(locations="classpath:applicationContext-test.xml")
@TransactionConfiguration(transactionManager="txManager", defaultRollback=true)
@Transactional
public abstract class IntegrationTestBase extends AbstractTransactionalJUnit4SpringContextTests
{
@PersistenceContext
protected EntityManager em;
@Autowired
protected SomeService serviceAvailableToSubclasses;
@Before
public void beforeEachTest()
{
//fill database with testdata and whatever you need to, runs before each test in extending classes
}
@After
public void afterEachTest()
{
//Do something, if you need to, or just remove this
}
}
從此擴展,您可以在派生類中使用@ Transactional,@ Autowired等,或派生更具體的抽象測試基類(例如,對於不同類型的測試,我具有IntegrationSessionTestBase和IntegrationSessionNewRequestPerTestBase,每個測試需要新的會話和/或請求)。
我已經用一個簡單的基於JPA(Hibernate)的應用程序做到了。
<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.soebes.casestudy</groupId>
<artifactId>casestudy</artifactId>
<packaging>jar</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>Case Study Pizza Ordering</name>
<url>Pizza Ordering</url>
<properties>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<hibernate-core-version>3.4.0.GA</hibernate-core-version>
<database.driverClassName>com.mysql.jdbc.Driver</database.driverClassName>
<database.url>jdbc:mysql://localhost:3306/casestudy</database.url>
<database.dialect>org.hibernate.dialect.MySQLDialect</database.dialect>
<database.root.user>root</database.root.user>
<database.root.password>root</database.root.password>
<database.user>casestudy</database.user>
<database.password>casestudy</database.password>
<database.database>casestudy</database.database>
</properties>
<build>
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>hibernate3-maven-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<id>hibernate-create-schema</id>
<phase>generate-test-sources</phase>
<goals>
<goal>hbm2ddl</goal>
</goals>
<configuration>
<components>
<component>
<name>hbm2ddl</name>
<implementation>annotationconfiguration</implementation>
</component>
</components>
<componentProperties>
<configurationfile>/src/main/resources/hibernate.cfg.xml</configurationfile>
<jdk5>true</jdk5>
<packagename>com.soebes.casestudy.bo</packagename>
<console>false</console>
<outputfilename>create.sql</outputfilename>
<drop>false</drop>
<create>true</create>
<update>false</update>
<export>false</export>
<format>true</format>
</componentProperties>
</configuration>
</execution>
<execution>
<id>hibernate-drop-schema</id>
<phase>generate-test-sources</phase>
<goals>
<goal>hbm2ddl</goal>
</goals>
<configuration>
<components>
<component>
<name>hbm2ddl</name>
<implementation>annotationconfiguration</implementation>
</component>
</components>
<componentProperties>
<configurationfile>/src/main/resources/hibernate.cfg.xml</configurationfile>
<jdk5>true</jdk5>
<packagename>com.soebes.casestudy.bo</packagename>
<console>false</console>
<outputfilename>drop.sql</outputfilename>
<drop>true</drop>
<create>false</create>
<update>false</update>
<export>false</export>
<format>true</format>
</componentProperties>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.9</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.8</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>sql-maven-plugin</artifactId>
<version>1.4</version>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.9</version>
</dependency>
</dependencies>
<!-- common configuration shared by all executions -->
<configuration>
<driver>${database.driverClassName}</driver>
<url>${database.url}</url>
<username>${database.root.user}</username>
<password>${database.root.password}</password>
</configuration>
<executions>
<execution>
<id>drop-database</id>
<phase>generate-test-resources</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<sqlCommand>
DROP DATABASE IF EXISTS casestudy;
CREATE DATABASE casestudy;
GRANT ALL ON casestudy.* TO ${database.user} IDENTIFIED BY '${database.password}';
</sqlCommand>
</configuration>
</execution>
<execution>
<id>create-database</id>
<phase>generate-test-resources</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<sqlCommand>
USE casestudy;
</sqlCommand>
<srcFiles>
<srcFile>${project.build.directory}/hibernate3/sql/create.sql</srcFile>
</srcFiles>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>${hibernate-core-version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>3.3.0.SP1</version>
</dependency>
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.4.GA</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>5.14.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.9</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.13</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.1</version>
</dependency>
</dependencies>
</project>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.