Last night with the help of loraxorg on the Spring Forums I got integration testing working under Maven 2 with Struts 2, Spring, and Hibernate JPA working. This was failing priorly due to a transient dependency in Maven 2 to an old version of Xerces. (See the Spring Forum thread for the solution.)
I have not done a lot of test driven development in the past, and personally I don't really get a lot of value out of isolated Unit tests. Integration testing on the other hand I like. Real data, real connections, real functionality, and at the moment for me real failures. I'd rather know now though.
One of the main issues in using JUnit for integration testing is that it instantiates a copy of your test class for each test in the class. This guarantees an isolated environment for testing, but present issues with integration testing. The main issue is that you don't want to have to reload your Spring context over and over again. In my case this is painful because Spring also triggers the initialization of my persistence context.
The Code
To overcome this I created a factory class that stores the references to my application context in a static member, and has a static method for getting a handle to the context.
Notice that is written in Groovy. I'm using Groovy for all of my test cases. The same principles would apply to a factory class written in Java. I have two potential application contexts, a simple one that only has a datasource, and my full one supporting my JPA environment, and all of my Struts 2 action beans, DAO's and service beans. In other words my whole application environment.
Here's a sample test of a DAO:
I simply use my factory to get a handle to my Spring ApplicationContext, and use it to get a "shipmentDao." Then I can call any methods on it I like, testing the results.
Testing a Struts 2 Action is substantially the same.
I use my SpringContextTestFactory to get a handle to my ApplicationContext, and get a "listShipmentsAction" bean. The listShipmentsAction beans has a dependency on a ShippingManager service bean, which has a dependency on a ShipmentDao bean, which has a dependency on a JPA EntityManagerFactory. All of these dependencies are injected by Spring, giving me an action I can test against my database.
I instantiate a ListShipmentsModel, which holds my query parameters, plug in a value, set the model on the action, and call the action's execute method. Once the action has executed I can check the results any way I'd like. In this case there is a list "shipments" that is a member of the action, I check to be sure that its size is greater than 0.
Configuring Maven 2
To get all of this running you need to:
Configure Maven to use Groovy and compile your Groovy test classes.
Configure Maven to run your integration tests.
Exclude your integration tests from normal test runs.
Fix the Xerces dependency.
Configuring Maven to compile Groovy files is quite easy. Just add the following to your <build><plugins> section.
Now we need to create a profile that tells Maven to run our itegration tests.
This profile attaches itself to the integration test phase and only runs test that end in ITest. (I'm not sure why the include uses **/*ITest.java, but it works.) If you already have profiles configured leave off the profiles tags.
Then we need to exclude the integration tests from our unit test run. This snipped goes in your <build><plugins> section.
The final issue you need to take care of is speficying the correct xerces dependency. Add the following to your dependencies:
That tells Maven to use Xerces 2.8.1 when running tests.
I place my Groovy test files in src/test/java. I don't have a separate directory for them. You could do that by configuring the Groovy compilation to look elsewhere very easily. I haven't done it because all of my tests are in Groovy, and well, I'm lazy.
原文地址:http://www.vitarara.org/cms/struts_2_cookbook/integration_testing
I have not done a lot of test driven development in the past, and personally I don't really get a lot of value out of isolated Unit tests. Integration testing on the other hand I like. Real data, real connections, real functionality, and at the moment for me real failures. I'd rather know now though.
One of the main issues in using JUnit for integration testing is that it instantiates a copy of your test class for each test in the class. This guarantees an isolated environment for testing, but present issues with integration testing. The main issue is that you don't want to have to reload your Spring context over and over again. In my case this is painful because Spring also triggers the initialization of my persistence context.
The Code
To overcome this I created a factory class that stores the references to my application context in a static member, and has a static method for getting a handle to the context.
package net.vitarara.quadran.core.test; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.context.ApplicationContext; class SpringContextTestFactory { private static final jpaContext private static final datasourceContext public static ApplicationContext getJpaContext () { if (jpaContext == null) { jpaContext = new ClassPathXmlApplicationContext ("classpath*:applicationContext.xml"); } return jpaContext } public static ApplicationContext getDatasourceContext () { if (datasourceContext == null) { datasourceContext = new ClassPathXmlApplicationContext ("classpath*:test-applicationContext.xml"); } return datasourceContext } }
Notice that is written in Groovy. I'm using Groovy for all of my test cases. The same principles would apply to a factory class written in Java. I have two potential application contexts, a simple one that only has a datasource, and my full one supporting my JPA environment, and all of my Struts 2 action beans, DAO's and service beans. In other words my whole application environment.
Here's a sample test of a DAO:
package net.vitarara.quadran.core.data.jpa; import net.vitarara.quadran.core.data.*; import net.vitarara.quadran.core.test.SpringContextTestFactory; import org.springframework.context.ApplicationContext; class ShipmentDaoITest extends GroovyTestCase { void testFindForOutstandingOblReport () { def dao = SpringContextTestFactory.getJpaContext().getBean ("shipmentDao"); def shipments = dao.findForOutstandingOblReport (); assertTrue ("Issuficient records returned", shipments.size > 20); } }
I simply use my factory to get a handle to my Spring ApplicationContext, and use it to get a "shipmentDao." Then I can call any methods on it I like, testing the results.
Testing a Struts 2 Action is substantially the same.
package net.vitarara.quadran.core.web.shipping import net.vitarara.quadran.core.test.SpringContextTestFactory; class ListShipmentsITest extends GroovyTestCase { void testFindByOrderNumber () { def action = SpringContextTestFactory.getJpaContext().getBean ("listShipmentsAction"); def model = new ListShipmentsModel () model.orderNumber = "SI142784" action.model = model action.execute () assertTrue ("No shipments were found", action.shipments.size > 0) } }
I use my SpringContextTestFactory to get a handle to my ApplicationContext, and get a "listShipmentsAction" bean. The listShipmentsAction beans has a dependency on a ShippingManager service bean, which has a dependency on a ShipmentDao bean, which has a dependency on a JPA EntityManagerFactory. All of these dependencies are injected by Spring, giving me an action I can test against my database.
I instantiate a ListShipmentsModel, which holds my query parameters, plug in a value, set the model on the action, and call the action's execute method. Once the action has executed I can check the results any way I'd like. In this case there is a list "shipments" that is a member of the action, I check to be sure that its size is greater than 0.
Configuring Maven 2
To get all of this running you need to:
Configure Maven to use Groovy and compile your Groovy test classes.
Configure Maven to run your integration tests.
Exclude your integration tests from normal test runs.
Fix the Xerces dependency.
Configuring Maven to compile Groovy files is quite easy. Just add the following to your <build><plugins> section.
<plugin> <artifactId>maven-antrun-plugin</artifactId> <executions> <execution> <id>compile</id> <phase>compile</phase> <configuration> <tasks> <taskdef name="groovyc" classname="org.codehaus.groovy.ant.Groovyc"> <classpath refid="maven.compile.classpath"/> </taskdef> <mkdir dir="${project.build.outputDirectory}"/> <groovyc destdir="${project.build.outputDirectory}" srcdir="${basedir}/src/main/java/" listfiles="true"> <classpath refid="maven.compile.classpath"/> </groovyc> </tasks> </configuration> <goals> <goal>run</goal> </goals> </execution> <execution> <id>test-compile</id> <phase>test-compile</phase> <configuration> <tasks> <taskdef name="groovyc" classname="org.codehaus.groovy.ant.Groovyc"> <classpath refid="maven.compile.classpath"/> </taskdef> <mkdir dir="${project.build.testOutputDirectory}"/> <groovyc destdir="${project.build.testOutputDirectory}" srcdir="${basedir}/src/test/java/" listfiles="true"> <classpath refid="maven.test.classpath"/> </groovyc> </tasks> </configuration> <goals> <goal>run</goal> </goals> </execution> </executions> </plugin>
Now we need to create a profile that tells Maven to run our itegration tests.
<profiles> <profile> <id>itest</id> <activation> <property> <name>itest</name> </property> </activation> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <executions> <execution> <id>surefire-it</id> <phase>integration-test</phase> <goals> <goal>test</goal> </goals> <configuration> <excludes> <exclude>none</exclude> </excludes> <includes> <include>**/*ITest.java</include> </includes> </configuration> </execution> </executions> </plugin> </plugins> </build> </profile> </profiles>
This profile attaches itself to the integration test phase and only runs test that end in ITest. (I'm not sure why the include uses **/*ITest.java, but it works.) If you already have profiles configured leave off the profiles tags.
Then we need to exclude the integration tests from our unit test run. This snipped goes in your <build><plugins> section.
<plugin> <artifactId>maven-surefire-plugin</artifactId> <configuration> <excludes> <exclude>**/*ITest.java</exclude> </excludes> </configuration> </plugin>
The final issue you need to take care of is speficying the correct xerces dependency. Add the following to your dependencies:
<dependency> <groupId>xerces</groupId> <artifactId>xercesImpl</artifactId> <version>2.8.1</version> <scope>test</scope> </dependency>
That tells Maven to use Xerces 2.8.1 when running tests.
I place my Groovy test files in src/test/java. I don't have a separate directory for them. You could do that by configuring the Groovy compilation to look elsewhere very easily. I haven't done it because all of my tests are in Groovy, and well, I'm lazy.
原文地址:http://www.vitarara.org/cms/struts_2_cookbook/integration_testing
相关推荐
* Spring web: Spring MVC, Spring Web Flow 2, Spring Roo, other dynamic scripting, integration with popular Grails Framework (and Groovy), REST/web services, and more. This book guides you step by ...
- **Mocking与Integration Testing**:Struts2提供了MockStruts工具,方便对Action进行单元测试和集成测试。 10. **与其他框架的集成** - **Spring集成**:Struts2可以轻松与Spring框架集成,实现依赖注入和事务...
3. **13.3 集成测试**:介绍了Spring的Integration Testing框架,用于测试应用程序的不同组件之间的交互。 总的来说,《跟我学Spring3》涵盖了Spring在ORM支持、事务管理、Web框架集成、SSH集成开发以及零配置和...
Spring 框架由多个模块组成,包括核心容器(Core Container)、数据访问/集成(Data Access/Integration)、Web、AOP、工具(Tools)和测试(Testing)。核心容器包括核心模块、 Beans 模块、Context 模块和表达式...
10. **Integration Testing Support**:Spring3提供了全面的测试支持,包括单元测试、集成测试和端到端的Web应用测试。 11. **Spring Web Flow**:这是一个独立的模块,用于管理用户交互流程,特别适合构建复杂的...
2. Data Access/Integration:涵盖JDBC、JMS、JMX等技术的使用,以及与各种持久层框架(如Hibernate、MyBatis)的集成。 3. Web:详细介绍了Spring的Web MVC框架,包括DispatcherServlet、HandlerMapping、...
5. 应用场景:Spring广泛应用于企业级JavaEE应用开发,如SSH(Spring、Struts、Hibernate)和SSM(Spring、SpringMVC、MyBatis)等经典组合。它能够用于构建后端服务、数据库操作、Web应用、消息处理等各种场景,...
5. **框架集成**:Spring可以轻松地与其他优秀框架(如Struts、Hibernate、MyBatis、Quartz等)协同工作。 6. **降低API使用难度**:Spring对复杂的Java EE API进行了封装,如JDBC、JavaMail等,让开发者更易使用。 ...
- **Integration with Frameworks**: Examples of integrating XDoclet with popular web frameworks like Struts and Spring. #### Chapter 5: XDoclet and Web Frameworks Building on the previous chapter, ...
SSH 框架是指 Struts、Spring、Hibernate 三个框架的组合,用于开发基于 WEB 的应用程序。 5. JSP and HTML(JSP 和 HTML) JSP 和 HTML 是用于开发 WEB 应用程序的标记语言,JSP 是 Java 服务器页面,HTML 是超...
15. **Testing与Continuous Integration**:单元测试、集成测试和自动化构建是软件开发的重要环节。Junit、Mockito、Maven和Gradle等工具应熟练掌握。 16. **Design Patterns**:理解并应用设计模式,如工厂模式、...