- 浏览: 32000 次
- 性别:
- 来自: 天津
最新评论
-
crazywen2011:
...
WebService的WSDL编写 -
307622798:
其实学一下也挺好的,总是用CXF去自动生成有时也麻烦,呵呵。
WebService的WSDL编写 -
de6566088:
gao_xianglong 写道介绍的详细的,但企业开发一般相 ...
WebService的WSDL编写 -
de6566088:
lang330965445 写道支持下,心得体会很好
谢谢支持 ...
WebService的WSDL编写 -
gao_xianglong:
介绍的详细的,但企业开发一般相对都会采用第三方生成wsdl文件 ...
WebService的WSDL编写
作者原地址:http://yangblog.iteye.com/blog/964369
今天对着spring的文档看了spring-test这节,现在赶紧记下来,有错误之处还请指出。
spring可以基于junit3.8、junit4.4、testNG的环境,但是注意基于junit4.4和testNG要在java1.4(包括1.4)以上的版本。
首先环境(一):spring2.5.4、junit3.8、java1.6、eclipse
使用junit3.8有两种测试的方法,两种测试方法分别extends不同的类,我们一个一个来。
第一种方法A:
A方法要求测试的类继承org.springframework.test包中类,我们先来看看这个包的类的继承关系:
AbstractSpringContextTests
|
AbstractSingleSpringContextTests
|
AbstractDependencyInjectionSpringContextTests
|
AbstractTransactionalSpringContextTests
|
AbstractTransactionalDataSourceSpringContextTests
最上面的是父类,接着第二个继承第一个以此类推。
好了我们看看 AbstractSpringContextTests
- /**
- * Map of context keys returned by subclasses of this class, to Spring
- * contexts. This needs to be static, as JUnit tests are destroyed and
- * recreated between running individual test methods.
- */
- private static Map contextKeyToContextMap = new HashMap();
- /**
- * Default constructor for AbstractSpringContextTests.
- */
- public AbstractSpringContextTests() {
- }
- /**
- * Constructor for AbstractSpringContextTests with a JUnit name.
- */
- public AbstractSpringContextTests(String name) {
- super(name);
- }
/** * Map of context keys returned by subclasses of this class, to Spring * contexts. This needs to be static, as JUnit tests are destroyed and * recreated between running individual test methods. */ private static Map contextKeyToContextMap = new HashMap(); /** * Default constructor for AbstractSpringContextTests. */ public AbstractSpringContextTests() { } /** * Constructor for AbstractSpringContextTests with a JUnit name. */ public AbstractSpringContextTests(String name) { super(name); }
- /**
- * Load a new ApplicationContext for the given key.
- * <p>
- * To be implemented by subclasses.
- *
- * @param key the context key
- * @return the corresponding ApplicationContext instance (new)
- */
- protected abstract ConfigurableApplicationContext loadContext(Object key) throws Exception;
/** * Load a new ApplicationContext for the given key. * <p> * To be implemented by subclasses. * * @param key the context key * @return the corresponding ApplicationContext instance (new) */ protected abstract ConfigurableApplicationContext loadContext(Object key) throws Exception;
注意看这个static Map contextKeyToContextMap 这个是用来存放context的缓存区,作用稍后在说,
看下面的这个抽象方法,它的作用是用来loadContext,这方法的实现在它子类AbstractSingleSpringContextTests
中。看AbstractSingleSpringContextTests中的实现:
- /**
- * <p>
- * This implementation assumes a key of type String array and loads a
- * context from the given locations.
- * </p>
- * <p>
- * If you override {@link #contextKey()}, you will typically have to
- * override this method as well, being able to handle the key type that
- * <code>contextKey()</code> returns.
- * </p>
- *
- * @see #getConfigLocations()
- */
- protected ConfigurableApplicationContext loadContext(Object key) throws Exception {
- return loadContextLocations((String[]) key);
- }
- protected ConfigurableApplicationContext loadContextLocations(String[] locations) throws Exception {
- ++this.loadCount;
- if (this.logger.isInfoEnabled()) {
- this.logger.info("Loading context for locations: " + StringUtils.arrayToCommaDelimitedString(locations));
- }
- return createApplicationContext(locations);
- }
- protected ConfigurableApplicationContext createApplicationContext(final String[] locations) {
- GenericApplicationContext context = new GenericApplicationContext();
- customizeBeanFactory(context.getDefaultListableBeanFactory());
- createBeanDefinitionReader(context).loadBeanDefinitions(locations);
- context.refresh();
- return context;
- }
/** * <p> * This implementation assumes a key of type String array and loads a * context from the given locations. * </p> * <p> * If you override {@link #contextKey()}, you will typically have to * override this method as well, being able to handle the key type that * <code>contextKey()</code> returns. * </p> * * @see #getConfigLocations() */ protected ConfigurableApplicationContext loadContext(Object key) throws Exception { return loadContextLocations((String[]) key); } protected ConfigurableApplicationContext loadContextLocations(String[] locations) throws Exception { ++this.loadCount; if (this.logger.isInfoEnabled()) { this.logger.info("Loading context for locations: " + StringUtils.arrayToCommaDelimitedString(locations)); } return createApplicationContext(locations); } protected ConfigurableApplicationContext createApplicationContext(final String[] locations) { GenericApplicationContext context = new GenericApplicationContext(); customizeBeanFactory(context.getDefaultListableBeanFactory()); createBeanDefinitionReader(context).loadBeanDefinitions(locations); context.refresh(); return context; }
可以看到这个方法的实现了加载配置文件的作用,那我们怎么将我们的配置文件给AbstractSingleSpringContextTests
让它加载呢,AbstractSingleSpringContextTests有一个让我们测试类继承的方法String[] getConfigLocations()
- protected String[] getConfigLocations() {
- String[] paths = getConfigPaths();
- String[] locations = new String[paths.length];
- for (int i = 0; i < paths.length; i++) {
- String path = paths[i];
- if (path.startsWith("/")) {
- locations[i] = ResourceUtils.CLASSPATH_URL_PREFIX + path;
- }
- else {
- locations[i] = ResourceUtils.CLASSPATH_URL_PREFIX +
- StringUtils.cleanPath(ClassUtils.classPackageAsResourcePath(getClass()) + "/" + path);
- }
- }
- return locations;
- }
protected String[] getConfigLocations() { String[] paths = getConfigPaths(); String[] locations = new String[paths.length]; for (int i = 0; i < paths.length; i++) { String path = paths[i]; if (path.startsWith("/")) { locations[i] = ResourceUtils.CLASSPATH_URL_PREFIX + path; } else { locations[i] = ResourceUtils.CLASSPATH_URL_PREFIX + StringUtils.cleanPath(ClassUtils.classPackageAsResourcePath(getClass()) + "/" + path); } } return locations; }
在上面所说的loadContext的方法中会调用getConfigLocations()获得配置文件的位置,所以我们在我们测试的类中重写这个方法,这样就覆盖了这个方法。所以我们的测试类应该这样写
- public class TeacherDao2Test extends AbstractSingleSpringContextTests{
- protected String entryYear = "2010";
- protected Long gradeId = 1L;
- protected Long classId = 1L;
- protected Long subjectId = 1L;
- protected Long markId = 1L;
- protected Date toDate = new Date();
- protected Date fromDate;
- protected ApplicationContext app;
- // @Resource
- private GenericManager<AdjustedRateStandard, Long> adjustedRateStandardManager;
- protected TeacherDao2 teacherDao2;
- @Override
- protected String[] getConfigLocations() {
- return new String[] {"classpath:applicationContext-resources.xml",
- "classpath:WEB-INF/applicationContext.xml",
- "classpath:applicationContext-dao.xml"};
- }
- public void testGetQualityReviewResultArrayByDate() throws Exception {
- GenericManager<AdjustedRateStandard, Long> adjustedRateStandardManager = (GenericManager<AdjustedRateStandard, Long>) this.getApplicationContext().getBean("adjustedRateStandardManager");
- List<AdjustedRateStandard> a = adjustedRateStandardManager.getAll();
- for(AdjustedRateStandard ar : a) {
- System.out.println(ar.getId());
- System.out.println(ar.getRate());
- System.out.println(ar.getDescription());
- }
- System.out.println("--------------");
- /* a = adjustedRateDao.getAll();
- for(AdjustedRate ar : a) {
- System.out.println(ar.getAreaRate());
- System.out.println(ar.getSubject().getName());
- }*/
- }
- public void testa() {
- /*System.out.println();
- Double x = 2.0;
- Double y = 3.0;
- Double z = 1.2;
- BigDecimal xb = new BigDecimal(String.valueOf(x));
- BigDecimal yb = new BigDecimal(String.valueOf(y));
- BigDecimal zb = new BigDecimal(String.valueOf(z));
- System.out.println(x*y*z);
- System.out.println(xb.multiply(zb).multiply(yb));
- double d = xb.multiply(zb).multiply(yb).doubleValue();
- System.out.println(d);*/
- int[] a = {3,5,9,7,4,13,15,0,2,20};
- boolean[] b = new boolean[21];
- for(int i=0;i<a.length;i++) {
- b[a[i]] = true;
- }
- for(int i=0;i<b.length;i++) {
- if(b[i]) {
- System.out.print(i+",");
- }
- }
- }
- }
public class TeacherDao2Test extends AbstractSingleSpringContextTests{ protected String entryYear = "2010"; protected Long gradeId = 1L; protected Long classId = 1L; protected Long subjectId = 1L; protected Long markId = 1L; protected Date toDate = new Date(); protected Date fromDate; protected ApplicationContext app; // @Resource private GenericManager<AdjustedRateStandard, Long> adjustedRateStandardManager; protected TeacherDao2 teacherDao2; @Override protected String[] getConfigLocations() { return new String[] {"classpath:applicationContext-resources.xml", "classpath:WEB-INF/applicationContext.xml", "classpath:applicationContext-dao.xml"}; } public void testGetQualityReviewResultArrayByDate() throws Exception { GenericManager<AdjustedRateStandard, Long> adjustedRateStandardManager = (GenericManager<AdjustedRateStandard, Long>) this.getApplicationContext().getBean("adjustedRateStandardManager"); List<AdjustedRateStandard> a = adjustedRateStandardManager.getAll(); for(AdjustedRateStandard ar : a) { System.out.println(ar.getId()); System.out.println(ar.getRate()); System.out.println(ar.getDescription()); } System.out.println("--------------"); /* a = adjustedRateDao.getAll(); for(AdjustedRate ar : a) { System.out.println(ar.getAreaRate()); System.out.println(ar.getSubject().getName()); }*/ } public void testa() { /*System.out.println(); Double x = 2.0; Double y = 3.0; Double z = 1.2; BigDecimal xb = new BigDecimal(String.valueOf(x)); BigDecimal yb = new BigDecimal(String.valueOf(y)); BigDecimal zb = new BigDecimal(String.valueOf(z)); System.out.println(x*y*z); System.out.println(xb.multiply(zb).multiply(yb)); double d = xb.multiply(zb).multiply(yb).doubleValue(); System.out.println(d);*/ int[] a = {3,5,9,7,4,13,15,0,2,20}; boolean[] b = new boolean[21]; for(int i=0;i<a.length;i++) { b[a[i]] = true; } for(int i=0;i<b.length;i++) { if(b[i]) { System.out.print(i+","); } } } }
这样的话测试类体通过getApplicationContext()就可以获得一个AplicationContext的对象,这个对象可以直接用getbean方法获得spring的容器中的对象了。
在AbstractSingleSpringContextTests类中只是简单的加载了容器,当使用AbstractDependencyInjectionSpringContextTests
类(及其子类)载入你的应用上下文时, 它们可以通过Setter注入选择性配置你的测试类实例。你需要做的仅仅是定义实例变量和相应的setter方法。 AbstractDependencyInjectionSpringContextTests
将在getConfigLocations()
方法定义的配置文件集中自动查找相应对象,注意它使用的是按类型自动装配,因此如果你有多个bean定义是相同的类型,就不能在这些bean中使用这种方法。 这种情况下,你可以使用继承的applicationContext
实例变量并实现显式的查找(比如), 调用applicationContext.getBean("id")
方法。
如果你不希望在测试案例中使用依赖注入,只要不声明任何public
setter方法就可以简单实现。 作为替代的,你可以扩展AbstractSpringContextTests
- 在org.springframework.test
包中的JUnit 3.8集成测试支持类层次的根 - 它仅仅包含了一些载入Spring上下文的简单方法,而且不在测试fixture中使用依赖注入。
AbstractTransactionalSpringContextTests
类 依赖于应用上下文中定义的PlatformTransactionManager
bean。 名字是无关紧要的,因为使用了按类型自动装配,通常你会扩展其子类AbstractTransactionalDataSourceSpringContextTests
。 这个类也需要在应用上下文中有一个DataSource
bean定义(同样可以是任意名称)。 它创建一个JdbcTemplate
实例变量,可以用来方便的查询和删除选定表的内容( 请记住默认情况下事务将被回滚,因而这样做是安全的)。
最后说说context缓存的问题,在每个测试的方法被执行的之前都会去加载一次配置文件,所以在spring第一次加载成功以后会将加载的文件名字为key,加载的得到的context为vlaue存在 contextKeyToContextMap ,这样下载在加载的时候就会先去 contextKeyToContextMap 找看有没有对应的key有的话就直接获得context。在一些少见的会“污染”应用上下文的案例中需要重新载入—— 例如,改变一个bean定义或应用对象的状态—— Spring的测试支持提供了在执行下一个测试前让测试fixture重新载入配置并重建应用上下文的机制。方法就是使用AbstractSingleSpringContextTests类中的 setDirty()
方法来让测试fixture在执行下一个测试案例时重新载 AbstractAnnotationAwareTransactionalTests
类,这个方法就是将contextKeyToContextMap 里的对应的记录给remove掉。
第二种方法B:
我们也可以使用我们的测试类继承AbstractJUnit38SpringContextTests这个类,这是使用Spring TestContext Framework
框架的核心包括TestContext
和TestContextManager
类以及TestExecutionListener
接口。 每次测试都会创建TestContextManager
。TestContextManager
管理了一个TestContext
, 它负责持有当前测试的上下文。TestContextManager
还负责在测试执行过程中更新TestContext
的状态并代 理到TestExecutionListener
, 它用来监测测试实际的执行(如提供依赖注入、管理事务等等)。其实也就是在TestContextManager有一个TestExecutionListener的list,在每次执行测试方法前后是时候都会遍历这个list并执行对应的prepareTestInstance和beforeTestMethod和afterTestMethod方法。
-
TestContext
:封装测试执行的上下文,与当前使用的测试框架无关。 -
TestContextManager
:Spring TestContext Framework的主入口点, 负责管理单独的TestContext
并在定义好的执行点上向所有注册的TestExecutionListener
发出事件通知: 测试实例的准备,先于特定的测试框架的前置方法,迟于后置方法。 -
TestExecutionListener
:定义了一个监听器API与TestContextManager
发布的测试执行事件进行交互, 而该监听器就是注册到这个TestContextManager
上的。Spring提供了
TestExecutionListener
的三个实现, 他们都是使用默认值进行配置的(通过@TestExecutionListeners
注解):DependencyInjectionTestExecutionListener
、DirtiesContextTestExecutionListener
及TransactionalTestExecutionListener
, 他们对测试实例提供了依赖注入支持,处理@DirtiesContext
注解,并分别使用默认的回滚语义对测试提供事务支持。
好了,直接上例子:
- @ContextConfiguration(locations = {"classpath:applicationContext-resources.xml",
- "classpath:WEB-INF/applicationContext.xml",
- "classpath:applicationContext-dao.xml"})
- public class TeacherDao2Test extends AbstractJUnit38SpringContextTests {
- protected String entryYear = "2010";
- protected Long gradeId = 1L;
- protected Long classId = 1L;
- protected Long subjectId = 1L;
- protected Long markId = 1L;
- protected Date toDate = new Date();
- protected Date fromDate;
- protected ApplicationContext app;
- @Resource
- private GenericManager<AdjustedRateStandard, Long> adjustedRateStandardManager;
- protected TeacherDao2 teacherDao2;
- public void testGetQualityReviewResultArrayByDate() throws Exception {
- // GenericManager<AdjustedRateStandard, Long> adjustedRateStandardManager = (GenericManager<AdjustedRateStandard, Long>) this.getApplicationContext().getBean("adjustedRateStandardManager");
- Assert.assertNotNull("not null", adjustedRateStandardManager);
- List<AdjustedRateStandard> a = adjustedRateStandardManager.getAll();
- for(AdjustedRateStandard ar : a) {
- System.out.println(ar.getId());
- System.out.println(ar.getRate());
- System.out.println(ar.getDescription());
- }
- System.out.println("--------------");
- /* a = adjustedRateDao.getAll();
- for(AdjustedRate ar : a) {
- System.out.println(ar.getAreaRate());
- System.out.println(ar.getSubject().getName());
- }*/
- }
- public void testa() {
- /*System.out.println();
- Double x = 2.0;
- Double y = 3.0;
- Double z = 1.2;
- BigDecimal xb = new BigDecimal(String.valueOf(x));
- BigDecimal yb = new BigDecimal(String.valueOf(y));
- BigDecimal zb = new BigDecimal(String.valueOf(z));
- System.out.println(x*y*z);
- System.out.println(xb.multiply(zb).multiply(yb));
- double d = xb.multiply(zb).multiply(yb).doubleValue();
- System.out.println(d);*/
- int[] a = {3,5,9,7,4,13,15,0,2,20};
- boolean[] b = new boolean[21];
- for(int i=0;i<a.length;i++) {
- b[a[i]] = true;
- }
- for(int i=0;i<b.length;i++) {
- if(b[i]) {
- System.out.print(i+",");
- }
- }
- }
- }
@ContextConfiguration(locations = {"classpath:applicationContext-resources.xml", "classpath:WEB-INF/applicationContext.xml", "classpath:applicationContext-dao.xml"}) public class TeacherDao2Test extends AbstractJUnit38SpringContextTests { protected String entryYear = "2010"; protected Long gradeId = 1L; protected Long classId = 1L; protected Long subjectId = 1L; protected Long markId = 1L; protected Date toDate = new Date(); protected Date fromDate; protected ApplicationContext app; @Resource private GenericManager<AdjustedRateStandard, Long> adjustedRateStandardManager; protected TeacherDao2 teacherDao2; public void testGetQualityReviewResultArrayByDate() throws Exception { // GenericManager<AdjustedRateStandard, Long> adjustedRateStandardManager = (GenericManager<AdjustedRateStandard, Long>) this.getApplicationContext().getBean("adjustedRateStandardManager"); Assert.assertNotNull("not null", adjustedRateStandardManager); List<AdjustedRateStandard> a = adjustedRateStandardManager.getAll(); for(AdjustedRateStandard ar : a) { System.out.println(ar.getId()); System.out.println(ar.getRate()); System.out.println(ar.getDescription()); } System.out.println("--------------"); /* a = adjustedRateDao.getAll(); for(AdjustedRate ar : a) { System.out.println(ar.getAreaRate()); System.out.println(ar.getSubject().getName()); }*/ } public void testa() { /*System.out.println(); Double x = 2.0; Double y = 3.0; Double z = 1.2; BigDecimal xb = new BigDecimal(String.valueOf(x)); BigDecimal yb = new BigDecimal(String.valueOf(y)); BigDecimal zb = new BigDecimal(String.valueOf(z)); System.out.println(x*y*z); System.out.println(xb.multiply(zb).multiply(yb)); double d = xb.multiply(zb).multiply(yb).doubleValue(); System.out.println(d);*/ int[] a = {3,5,9,7,4,13,15,0,2,20}; boolean[] b = new boolean[21]; for(int i=0;i<a.length;i++) { b[a[i]] = true; } for(int i=0;i<b.length;i++) { if(b[i]) { System.out.print(i+","); } } } }
注意,这次我使用了注解@Resource来让spring来自己帮我进行注入,在前面一种方法使用@Resource不行,当然也可以AbstractJUnit38SpringContextTests 的protected ApplicationContext applicationContext来自己在spring中取得。
注意在类的定义处使用@ContextConfiguration注解来把配置文件的位子传递给测试类,@ContextConfiguration总共有3个配置的属性,其他两个是boolean类型inheritLocations以表明是否继承父类的locations和loader表示使用自己的context加载器。
这种方法上下文缓存的处理和第一种方法一样。但是与上面不同的是使用@DirtiesContext 这个注解来表示重新加载,使用@DirtiesContext 注解的前提是在TestExecutionListeners中加入DirtiesContextTestExecutionListener,而我们的AbstractJUnit38SpringContextTests 中已经设置了DirtiesContextTestExecutionListener,看:
- @TestExecutionListeners({DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class})
- public abstract class AbstractJUnit38SpringContextTests extends TestCase implements ApplicationContextAware {
- private static int disabledTestCount = 0;
- /**
- * Return the number of tests disabled in this environment.
- */
- public static int getDisabledTestCount() {
- return disabledTestCount;
- }
- ...
- }
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class}) public abstract class AbstractJUnit38SpringContextTests extends TestCase implements ApplicationContextAware { private static int disabledTestCount = 0; /** * Return the number of tests disabled in this environment. */ public static int getDisabledTestCount() { return disabledTestCount; } ... }
事务管理:
对事务的支持可以通过在TestExecutionListeners加入TransactionalTestExecutionListener,同时在类或方法上加上@Transactional就可以支持事务了,在对AbstractJUnit38SpringContextTests类进行扩展了事务和SimpleJdbcTemplate的子类AbstractTransactionalJUnit38SpringContextTests.class是这样配置的。
- @TestExecutionListeners({TransactionalTestExecutionListener.class})
- @Transactional
- public abstract class AbstractTransactionalJUnit38SpringContextTests extends AbstractJUnit38SpringContextTests {
- /**
- * The SimpleJdbcTemplate that this base class manages, available to subclasses.
- */
- protected SimpleJdbcTemplate simpleJdbcTemplate;
- private String sqlScriptEncoding;
- /**
- * Constructs a new AbstractTransactionalJUnit38SpringContextTests instance.
- */
- public AbstractTransactionalJUnit38SpringContextTests() {
- super();
- }
- }
@TestExecutionListeners({TransactionalTestExecutionListener.class}) @Transactional public abstract class AbstractTransactionalJUnit38SpringContextTests extends AbstractJUnit38SpringContextTests { /** * The SimpleJdbcTemplate that this base class manages, available to subclasses. */ protected SimpleJdbcTemplate simpleJdbcTemplate; private String sqlScriptEncoding; /** * Constructs a new AbstractTransactionalJUnit38SpringContextTests instance. */ public AbstractTransactionalJUnit38SpringContextTests() { super(); } }
所以我们可以使测试类继承这个类AbstractTransactionalJUnit38SpringContextTests
下面环境改变: spring2.5.4、junit4.4、java1.6、eclipse
同样的使用了Spring TestContext Framework,Spring TestContext Framework通过一个可定制的运行器提供了与JUnit 4.4的完全集成。 通过使用@Runwith(SpringJUnit4ClassRunner.class)
来注解测试类,开发者可以实现标准的JUnit 4.4单元和集成测试, 同时还能获得TestContext框架的好处,上例子
- @RunWith(SpringJUnit4ClassRunner.class)
- @TestExecutionListeners({DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class})
- public abstract class AbstractJUnit4SpringContextTests implements ApplicationContextAware {
- /**
- * Logger available to subclasses.
- */
- protected final Log logger = LogFactory.getLog(getClass());
- /**
- * The {@link ApplicationContext} that was injected into this test instance
- * via {@link #setApplicationContext(ApplicationContext)}.
- */
- protected ApplicationContext applicationContext;
- /**
- * Set the {@link ApplicationContext} to be used by this test instance,
- * provided via {@link ApplicationContextAware} semantics.
- */
- public final void setApplicationContext(final ApplicationContext applicationContext) {
- this.applicationContext = applicationContext;
- }
- }
@RunWith(SpringJUnit4ClassRunner.class) @TestExecutionListeners({DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class}) public abstract class AbstractJUnit4SpringContextTests implements ApplicationContextAware { /** * Logger available to subclasses. */ protected final Log logger = LogFactory.getLog(getClass()); /** * The {@link ApplicationContext} that was injected into this test instance * via {@link #setApplicationContext(ApplicationContext)}. */ protected ApplicationContext applicationContext; /** * Set the {@link ApplicationContext} to be used by this test instance, * provided via {@link ApplicationContextAware} semantics. */ public final void setApplicationContext(final ApplicationContext applicationContext) { this.applicationContext = applicationContext; } }
还有对事务和简单数据库访问的AbstractTransactionalJUnit4SpringContextTests
- @TestExecutionListeners({TransactionalTestExecutionListener.class})
- @Transactional
- public abstract class AbstractTransactionalJUnit4SpringContextTests extends AbstractJUnit4SpringContextTests {
- /**
- * The SimpleJdbcTemplate that this base class manages, available to subclasses.
- */
- protected SimpleJdbcTemplate simpleJdbcTemplate;
- private String sqlScriptEncoding;
- /**
- * Set the DataSource, typically provided via Dependency Injection.
- */
- @Autowired
- public void setDataSource(DataSource dataSource) {
- this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
- }
- /**
- * Specify the encoding for SQL scripts, if different from the platform encoding.
- * @see #executeSqlScript
- */
- public void setSqlScriptEncoding(String sqlScriptEncoding) {
- this.sqlScriptEncoding = sqlScriptEncoding;
- }
- /**
- * Count the rows in the given table.
- * @param tableName table name to count rows in
- * @return the number of rows in the table
- */
- protected int countRowsInTable(String tableName) {
- return SimpleJdbcTestUtils.countRowsInTable(this.simpleJdbcTemplate, tableName);
- }
- /**
- * Convenience method for deleting all rows from the specified tables.
- * Use with caution outside of a transaction!
- * @param names the names of the tables from which to delete
- * @return the total number of rows deleted from all specified tables
- */
- protected int deleteFromTables(String... names) {
- return SimpleJdbcTestUtils.deleteFromTables(this.simpleJdbcTemplate, names);
- }
- /**
- * Execute the given SQL script. Use with caution outside of a transaction!
- * <p>The script will normally be loaded by classpath. There should be one statement
- * per line. Any semicolons will be removed. <b>Do not use this method to execute
- * DDL if you expect rollback.</b>
- * @param sqlResourcePath the Spring resource path for the SQL script
- * @param continueOnError whether or not to continue without throwing an
- * exception in the event of an error
- * @throws DataAccessException if there is an error executing a statement
- * and continueOnError was <code>false</code>
- */
- protected void executeSqlScript(String sqlResourcePath, boolean continueOnError)
- throws DataAccessException {
- Resource resource = this.applicationContext.getResource(sqlResourcePath);
- SimpleJdbcTestUtils.executeSqlScript(
- this.simpleJdbcTemplate, new EncodedResource(resource, this.sqlScriptEncoding), continueOnError);
- }
- }
@TestExecutionListeners({TransactionalTestExecutionListener.class}) @Transactional public abstract class AbstractTransactionalJUnit4SpringContextTests extends AbstractJUnit4SpringContextTests { /** * The SimpleJdbcTemplate that this base class manages, available to subclasses. */ protected SimpleJdbcTemplate simpleJdbcTemplate; private String sqlScriptEncoding; /** * Set the DataSource, typically provided via Dependency Injection. */ @Autowired public void setDataSource(DataSource dataSource) { this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource); } /** * Specify the encoding for SQL scripts, if different from the platform encoding. * @see #executeSqlScript */ public void setSqlScriptEncoding(String sqlScriptEncoding) { this.sqlScriptEncoding = sqlScriptEncoding; } /** * Count the rows in the given table. * @param tableName table name to count rows in * @return the number of rows in the table */ protected int countRowsInTable(String tableName) { return SimpleJdbcTestUtils.countRowsInTable(this.simpleJdbcTemplate, tableName); } /** * Convenience method for deleting all rows from the specified tables. * Use with caution outside of a transaction! * @param names the names of the tables from which to delete * @return the total number of rows deleted from all specified tables */ protected int deleteFromTables(String... names) { return SimpleJdbcTestUtils.deleteFromTables(this.simpleJdbcTemplate, names); } /** * Execute the given SQL script. Use with caution outside of a transaction! * <p>The script will normally be loaded by classpath. There should be one statement * per line. Any semicolons will be removed. <b>Do not use this method to execute * DDL if you expect rollback.</b> * @param sqlResourcePath the Spring resource path for the SQL script * @param continueOnError whether or not to continue without throwing an * exception in the event of an error * @throws DataAccessException if there is an error executing a statement * and continueOnError was <code>false</code> */ protected void executeSqlScript(String sqlResourcePath, boolean continueOnError) throws DataAccessException { Resource resource = this.applicationContext.getResource(sqlResourcePath); SimpleJdbcTestUtils.executeSqlScript( this.simpleJdbcTemplate, new EncodedResource(resource, this.sqlScriptEncoding), continueOnError); } }
ok写完了,其中对spring的事务测试没有进行研究,改天补上。
补上事务:
主要是针对使用Spring TestContext Framework的事务测试。
前面已经提到,要使用事务,必须在TestExecutionListeners中加入TransactionalTestExecutionListener,
也就是在类名上使用注解@TestExecutionListeners({TransactionalTestExecutionListener.class})
(注意要是类没有使用@TestExecutionListeners注解或者@TestExecutionListeners为空包括所有父类,
那么spring会使用默认的Listener,也就是 DependencyInjectionTestExecutionListener
、
DirtiesContextTestExecutionListener
及TransactionalTestExecutionListener
),
但这还不够,还必须使用@Transactiona注解标明那个要使用事务,@Transactiona放在类名上时该类所有方法都会使用事务,
也可以放在测试的方法上,这样这个测试的方法就使用事务,要是想那个方法不使用事务可以使用注解@NoTransactiona;
最后因为spring需要一个transactionManager来进行管理,
所以我们需在配置文件中加入 transactionManager的一个bean,
当然也可以通过在类名上加上@TransactionConfiguration(transactionManager="txMgr", defaultRollback=true)这样决定使用那个transactionManager。不加的话就使用bean id为ransactionManager的。
这是spring配置:
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
- default-lazy-init="true">
- <!-- Hibernate SessionFactory -->
- <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
- <property name="dataSource" ref="dataSource"/>
- <property name="configLocation" value="classpath:hibernate.cfg.xml"/>
- <property name="hibernateProperties">
- <value>
- hibernate.dialect=${hibernate.dialect}
- hibernate.query.substitutions=true 'Y', false 'N'
- hibernate.cache.use_second_level_cache=true
- hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider
- </value>
- <!-- Turn batching off for better error messages under PostgreSQL -->
- <!-- hibernate.jdbc.batch_size=0 -->
- </property>
- </bean>
- <!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
- <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
- <property name="sessionFactory" ref="sessionFactory"/>
- </bean>
- <bean id="adjustedRateStandardDao" class="org.appfuse.dao.hibernate.GenericDaoHibernate">
- <constructor-arg value="com.waigi.integratedreport.model.AdjustedRateStandard"/>
- <property name="sessionFactory" ref="sessionFactory"/>
- </bean>
- <bean id="adjustedRateStandardManager" class="org.appfuse.service.impl.GenericManagerImpl">
- <constructor-arg ref="adjustedRateStandardDao" />
- </bean>
- </beans>
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd" default-lazy-init="true"> <!-- Hibernate SessionFactory --> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="configLocation" value="classpath:hibernate.cfg.xml"/> <property name="hibernateProperties"> <value> hibernate.dialect=${hibernate.dialect} hibernate.query.substitutions=true 'Y', false 'N' hibernate.cache.use_second_level_cache=true hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider </value> <!-- Turn batching off for better error messages under PostgreSQL --> <!-- hibernate.jdbc.batch_size=0 --> </property> </bean> <!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) --> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"/> </bean> <bean id="adjustedRateStandardDao" class="org.appfuse.dao.hibernate.GenericDaoHibernate"> <constructor-arg value="com.waigi.integratedreport.model.AdjustedRateStandard"/> <property name="sessionFactory" ref="sessionFactory"/> </bean> <bean id="adjustedRateStandardManager" class="org.appfuse.service.impl.GenericManagerImpl"> <constructor-arg ref="adjustedRateStandardDao" /> </bean> </beans>
测试类:
- package com.waigi.integratedreport.dao;
- import java.util.Calendar;
- import java.util.Date;
- import java.util.List;
- import javax.annotation.Resource;
- import org.appfuse.service.GenericManager;
- import org.junit.Assert;
- import org.junit.Before;
- import org.junit.Test;
- import org.junit.runner.RunWith;
- import org.springframework.context.ApplicationContext;
- import org.springframework.test.annotation.NotTransactional;
- import org.springframework.test.annotation.Rollback;
- import org.springframework.test.context.ContextConfiguration;
- import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
- import org.springframework.transaction.annotation.Transactional;
- import com.waigi.integratedreport.model.AdjustedRateStandard;
- @RunWith(SpringJUnit4ClassRunner.class)
- @ContextConfiguration(locations = {"classpath:applicationContext-resources.xml",
- "classpath:WEB-INF/applicationContext.xml",
- "classpath:applicationContext-dao.xml"})
- @Transactional
- public class TeacherDao2Test {
- protected String entryYear = "2010";
- protected Long gradeId = 1L;
- protected Long classId = 1L;
- protected Long subjectId = 1L;
- protected Long markId = 1L;
- protected Date toDate = new Date();
- protected Date fromDate;
- protected ApplicationContext app;
- @Resource
- private GenericManager<AdjustedRateStandard, Long> adjustedRateStandardManager;
- protected TeacherDao2 teacherDao2;
- @Before
- public void init() {
- Calendar c = Calendar.getInstance();
- System.out.println("init");
- c.clear();
- c.set(2010, 2, 1);
- fromDate = c.getTime();
- }
- @Test
- @NotTransactional
- public void testGetQualityReviewResultArrayByDate() throws Exception {
- // GenericManager<AdjustedRateStandard, Long> adjustedRateStandardManager = (GenericManager<AdjustedRateStandard, Long>) this.getApplicationContext().getBean("adjustedRateStandardManager");
- Assert.assertNotNull("not null", adjustedRateStandardManager);
- List<AdjustedRateStandard> a = adjustedRateStandardManager.getAll();
- for(AdjustedRateStandard ar : a) {
- System.out.println(ar.getId());
- System.out.println(ar.getRate());
- System.out.println(ar.getDescription());
- }
- System.out.println("--------------");
- /* a = adjustedRateDao.getAll();
- for(AdjustedRate ar : a) {
- System.out.println(ar.getAreaRate());
- System.out.println(ar.getSubject().getName());
- }*/
- }
- @Test
- @Rollback
- public void testSave() {
- AdjustedRateStandard ars = adjustedRateStandardManager.get(1L);
- ars.setDescription("第一名");
- adjustedRateStandardManager.save(ars);
- Assert.assertEquals("!=", ars, adjustedRateStandardManager.get(1L));
- System.out.println(adjustedRateStandardManager.get(1L).getDescription());
- }
- }
package com.waigi.integratedreport.dao; import java.util.Calendar; import java.util.Date; import java.util.List; import javax.annotation.Resource; import org.appfuse.service.GenericManager; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.context.ApplicationContext; import org.springframework.test.annotation.NotTransactional; import org.springframework.test.annotation.Rollback; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.transaction.annotation.Transactional; import com.waigi.integratedreport.model.AdjustedRateStandard; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:applicationContext-resources.xml", "classpath:WEB-INF/applicationContext.xml", "classpath:applicationContext-dao.xml"}) @Transactional public class TeacherDao2Test { protected String entryYear = "2010"; protected Long gradeId = 1L; protected Long classId = 1L; protected Long subjectId = 1L; protected Long markId = 1L; protected Date toDate = new Date(); protected Date fromDate; protected ApplicationContext app; @Resource private GenericManager<AdjustedRateStandard, Long> adjustedRateStandardManager; protected TeacherDao2 teacherDao2; @Before public void init() { Calendar c = Calendar.getInstance(); System.out.println("init"); c.clear(); c.set(2010, 2, 1); fromDate = c.getTime(); } @Test @NotTransactional public void testGetQualityReviewResultArrayByDate() throws Exception { // GenericManager<AdjustedRateStandard, Long> adjustedRateStandardManager = (GenericManager<AdjustedRateStandard, Long>) this.getApplicationContext().getBean("adjustedRateStandardManager"); Assert.assertNotNull("not null", adjustedRateStandardManager); List<AdjustedRateStandard> a = adjustedRateStandardManager.getAll(); for(AdjustedRateStandard ar : a) { System.out.println(ar.getId()); System.out.println(ar.getRate()); System.out.println(ar.getDescription()); } System.out.println("--------------"); /* a = adjustedRateDao.getAll(); for(AdjustedRate ar : a) { System.out.println(ar.getAreaRate()); System.out.println(ar.getSubject().getName()); }*/ } @Test @Rollback public void testSave() { AdjustedRateStandard ars = adjustedRateStandardManager.get(1L); ars.setDescription("第一名"); adjustedRateStandardManager.save(ars); Assert.assertEquals("!=", ars, adjustedRateStandardManager.get(1L)); System.out.println(adjustedRateStandardManager.get(1L).getDescription()); } }
从测试类可以看出,这个类的所有方法都使用了事务,除了有@NotTransactional注解的方法testGetQualityReviewResultArrayByDate,其次,加入事务的方法testsave()
可以通过注解@Rollback(value=false)来让这个事务提交而不是回滚,当然上面的实例虽然加了@Rollback但是它默认的
是true所以还是会回滚。
ol。
相关推荐
Struts2-Spring-Plugin-2.3.4.jar 是一个专门为 Struts 2 框架和 Spring 框架整合而设计的插件,主要用于处理 Struts 2 和 Spring 之间的集成问题。在Java Web开发中,这两个框架经常一起使用,Spring 提供了依赖...
在Spring Boot框架中,`druid-spring-boot-starter`是一个便捷的启动器,用于简化Druid的集成过程。通过引入这个启动器,我们可以快速地在Spring Boot项目中配置并使用Druid数据库连接池。`druid-spring-boot-...
这个压缩包包含三个子文件:mybatis-spring-1.2.3-javadoc.jar 提供了 API 文档,mybatis-spring-1.2.3.jar 是核心库,mybatis-spring-1.2.3-sources.jar 包含了源代码,方便开发者查看和学习。 1. **MyBatis-...
在没有Struts2-Spring-Plugin的情况下,要在Struts2应用中使用Spring,需要手动配置Action类与Spring Bean之间的关联。而有了这个插件,配置过程变得更加简单。以下是Struts2-Spring-Plugin-2.2.1.jar提供的主要功能...
spring单元测试包spring单元测试包spring单元测试包spring单元测试包spring单元测试包
在mybatis-spring-1.2.3-source.zip中,我们可以看到这些核心组件的实现细节。例如,SqlSessionFactoryBean是如何读取配置并创建SqlSessionFactory的,SqlSessionTemplate如何处理并发问题,以及MapperFactoryBean...
综上所述,《Pro-Spring-5》是学习和精通Spring框架的宝贵资源,结合书中的实例和源代码,开发者可以逐步掌握Spring的核心概念和技术,提升自己的开发技能。对于初学者来说,书中的书签和清晰的解释将使学习过程更为...
在 Spring Boot 中,可以使用 JUnit 或 TestNG 等测试框架来进行单元测试。单元测试的目的是为了确保单个类或方法的正确性和可靠性。 Spring 测试 Spring 测试是指对基于 Spring 框架的应用程序的测试。Spring ...
8. **单元测试**:如何利用Spring提供的TestContext框架进行单元测试,验证Bean的行为。 9. **运行和调试**:如何启动应用,查看控制台输出,以及如何使用断点进行调试。 10. **源码阅读**:对于压缩包中的代码,...
MyBatis-Spring 会帮助你将 MyBatis 代码无缝地整合到 Spring 中。 使用这个类库中的类, Spring 将会加载必要的 MyBatis 工厂类和 session 类。 这个类库也提供一个简单的方式来注入 MyBatis 数据映射器和 ...
这个jar包是根据源码打的,亲测过,好使,拿出来和大家分享一下。
在 `mybatis-spring-test` 模块中,提供了 `SqlSessionRule` 和 `SpringTestContextBootstrapper` 等工具类,方便进行单元测试。它们可以帮助快速搭建测试环境,模拟事务和数据源,使测试代码更加简洁。 总结: ...
配置spring和activemq时,遇到一些错误有可能是xbean-spring.jar包的版本低造成的。可以尝试使用xbean-spring-3.7.jar试试:) spring+activemq配置所需要的一个包文件。
单元测试是软件开发过程中不可或缺的一部分,它允许开发者独立地测试代码的各个部分,确保它们按照预期工作。Spring MVC 提供了对单元测试的良好支持,使得我们可以方便地测试控制器、服务层以及数据访问层。 在...
6. **支持 Spring 的测试框架**: 在测试环境中,MyBatis-Spring 可以帮助快速设置和清理数据库状态,便于单元测试。 使用 mybatis-spring-1.1.0.zip,你需要解压文件并将其包含的 JAR 文件添加到你的项目类路径中。...
- mybatis_spring_mapper_test:这部分内容可能是针对MyBatis-Spring整合后的Mapper接口的单元测试,通常会包含测试类,测试Mapper接口的方法是否能正确执行SQL并返回预期结果。 - mybatis_test:这部分可能涉及到...
jboss-spring-int-vfs.jar
在"spring-mybatis-spring-2.1.0.zip"这个资源包中,包含了Spring与MyBatis整合所需的全部组件,适用于各种Windows操作系统。这表明该版本已经经过了广泛的兼容性和稳定性测试,适合不同环境下的开发者使用。 1. **...
mybatis-spring-1.2.2-sources mybatis与spring的中间件的源代码,一般用mybatis,都要有这个中间件,调试必备啊