`
hotdog
  • 浏览: 282300 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Spring Test Context Framework

阅读更多
Hi Folks ....

Today we will see how effectively we use the infrastructure provided by Spring's Testing Context framework with examples.

From Spring 2.5.X , couple of annotations were added in their testing portfolio in package "org.springframework.test.annotation".

What is Spring Test Context Framework The Spring TestContext Framework provides several abstract support classes that simplify the writing of integration tests. These base test classes provide well-defined hooks into the testing framework as well as convenient instance variables and methods

Which means spring provides infrastructure , when you can hook custom implementation testing frameworks like

junit 3.* classAbstractTransactionalJUnit38SpringContextTests
junit 4.x class AbstractTransactionalJUnit4SpringContextTests
TestNG Framework AbstractTransactionalTestNGSpringContextTests
The Spring Framework provides the following set of Spring-specific annotations that you can use in your unit and integration tests in conjunction with the TestContext framework.

Annotations

   * @IfProfileValue
   * @ProfileValueSourceConfiguration
   * @DirtiesContext
   * @ExpectedException
   * @Timed
   * @Repeat
   * @Rollback
   * @NotTransactional
   * @Autowired
   * @Qualifier

@IfProfileValue

@IfProfileValue - Useful in executing test methods based on system level variables value configured . Normally we write Junit Test classes which can run any environment ( DEV - Development , PRD -Production, UAT -User Acceptance Test , INT - Integration ) , based on configurations like db properties ....

You need to create the System variable in pc with Name PRJ_ENV and value will be depending our environment

@IfProfileValue(name="PRJ_ENV", value="DEV")
public void testProcessWhichRunsOnlyOnRestrictedEnv() {
    // some logic that should run only on Development environment
}


If you want to make this test run on both DEV , UAT , Here goes the configurations

@IfProfileValue(name="PRJ_ENV", values={"DEV","UAT"})
// Since we didnt annotate with @ProfileValueSourceConfiguration frmk will check in system variable ,Since by default it uses SystemProfileValueSource
public void testProcessWhichRunsOnlyOnRestrictedEnv() {
    // some logic that should run only on Development and UAT environment
}


@ProfileValueSourceConfiguration

If @ProfileValueSourceConfiguration is not present on the specified class or if a custom ProfileValueSource is not declared, the default SystemProfileValueSource will be returned instead

Class-level annotation which is used to specify what type of ProfileValueSource to use when retrieving profile values configured via the @IfProfileValue annotation. If @ProfileValueSourceConfiguration is not declared for a test, SystemProfileValueSource will be used by default.

SystemProfileValueSource - will read the system level variable if our case it is PRJ_ENV

If we want to tune in such a way that key value pair exits in properties file (or) db we need to write a class say i.e CustomProfileValueSource implements ProfileValueSource and override get(String key) then configuration would be like

@IfProfileValue(name="PRJ_ENV", values={"DEV","UAT"})
@ProfileValueSourceConfiguration(CustomProfileValueSource.class)
public void testProcessWhichRunsOnlyOnRestrictedEnv() {
    // some logic that should run only on Developement and UAT enviroment
}


@DirtiesContext

The presence of this annotation on a test method indicates that the underlying Spring container is 'dirtied' during the execution of the test method, and thus must be rebuilt after the test method finishes execution (regardless of whether the test passed or not).

@DirtiesContext
public void testSaveNewPerson() {
    // some logic that results in the Spring container being dirtied
	// which means during the execution you through the code , if we try to change the value of bean instantiated by spring
	// to reset the same we will annotate the next calling method with @DirtiesContext which loads all bean freshly
}


@ExpectedException

Indicates that the annotated test method is expected to throw an exception during execution. The type of the expected exception is provided in the annotation, and if an instance of the exception is thrown during the test method execution then the test passes. Likewise if an instance of the exception is not thrown during the test method execution then the test fails.

//Can be used for Negative testing 
@ExpectedException(UserNotFoundException.class)
public void testLoginProcess() {
    // some logic that should result in an Exception being thrown	
}


@Timed

Indicates that the annotated test method has to finish execution in a specified time period (in milliseconds). If the text execution time takes longer than the specified time period, the test fails.

//In EJB way , we have TimeOut configuration , after which transaction in EJB Context will be automatically roll backed
@Timed(millis=1000)
public void testResponseWithinSecond() {
    // some logic that should not take longer than 1 second to execute
}


@Repeat

Indicates that the annotated test method must be executed repeatedly. The number of times that the test method is to be executed is specified in the annotation. If in class if setUp() and tearDown() is overridden (or) method is annotated these methods will also be called as many times as

configured in @Repeat annotation
@Repeat(10)
public void testProcessRepeatedlyForTenTimes() {
    // ...
}


@Rollback

If you use AbstractTransactionalSpringContextTests , tx will be automatically rollback Please check my page regarding the usage of "AbstractTransactionalSpringContextTests" @Rollback Indicates whether or not the transaction for the annotated test method should be rolled back after the test method has completed. If true, the transaction will be rolled back; otherwise, the transaction will be committed. Use @Rollback to override the default rollback flag configured at the class level.

@Rollback(false) // read-only tx
public void testProcessWithoutRollback() {
    // ...
}


@NotTransactional

The presence of this annotation indicates that the annotated test method must not execute in a transactional context.

//( No need to transaction manager definition in spring xml )
@NotTransactional 
public void testProcessWithoutTransaction() {
    // ...
}


Spring Test Context Framework

In below style of spring junit applicationContext.xml will read from classpath

@RunWith(SpringJUnit4ClassRunner.class)
/*
Defines class-level metadata which is used to determine how to load and configure an ApplicationContext. Specifically, @ContextConfiguration defines the application context resource locations to load as well as the ContextLoader strategy to use for loading the context.
*/
@ContextConfiguration(locations = {"classpath:/com/googlecode/jpractices/applicationContext.xml"})
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class})
public class UserServiceTest {
	/* Spring frmk will search is there any bean defined with TYPE of UserService to inject
	*/
    @Autowired
    private UserService userService;
    @Test
    public void doesUserExists() {
        boolean isUserExists = userService.doesUserExists("admin");
        assertTrue(true,isUserExists);
    }    
}


If bean declared in different name like <bean id="uSevice" class="com.jpractices.service.UserService" /> then we need to use @Qualifier in conjunction with @AutoWired like below

@Autowired
@Qualifier("uSevice")
private UserService userService;


@Qualifier can also be used in scenario's like , you had configured multiple datasources in spring xml and used spring autowiring super class for junit's to specify which datasource should be injected to which dao.

public void setDataSource(@Qualifier("myDataSource") DataSource dataSource) {
        super.setDataSource(dataSource);
}


Example from spring docuementation.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@TransactionConfiguration(transactionManager="txMgr", defaultRollback=false)
@Transactional
/* This class doesnt extend any spring frmk testing class like 'AbstractJUnit38SpringContextTests','AbstractTransactionalJUnit38SpringContextTests','AbstractTransactionalJUnit4SpringContextTests','AbstractTransactionalTestNGSpringContextTests' .... , instead it uses annotations )
public class FictitiousTransactionalTest {
 
/* Indicates that the annotated public void method should be executed before a transaction is started for test methods configured to run within a transaction via the @Transactional annotation.
*/
    @BeforeTransaction
    public void verifyInitialDatabaseState() {
        // logic to verify the initial state before a transaction is started
    }
 
    @Before
    public void setUpTestDataWithinTransaction() {
        // set up test data within the transaction
    }
 
    @Test
    // overrides the class-level defaultRollback setting
    @Rollback(true)
    public void modifyDatabaseWithinTransaction() {
        // logic which uses the test data and modifies database state
    }
 
    @After
    public void tearDownWithinTransaction() {
        // execute "tear down" logic within the transaction
    }
/*
Indicates that the annotated public void method should be executed after a transaction has been ended for test methods configured to run within a transaction via the @Transactional annotation.
*/
    @AfterTransaction
    public void verifyFinalDatabaseState() {
        // logic to verify the final state after transaction has rolled back
    }
 
    @Test
    @NotTransactional
    public void performNonDatabaseRelatedAction() {
        // logic which does not modify database state
    }
}





分享到:
评论

相关推荐

    org.spring-framework-3.0.4. 所有jar

    org.springframework.test-3.0.4.RELEASE.jar org.springframework.transaction-3.0.4.RELEASE.jar org.springframework.web.portlet-3.0.4.RELEASE.jar org.springframework.web.servlet-3.0.4.RELEASE.jar org...

    spring-framework-5.3.0-SNAPSHOT-dist.zip

    spring-framework-5.3.0-SNAPSHOT-dist, spring-aop, spring-aspects, spring-beans, spring-context, spring-context-indexer, spring-context-support, spring-core, spring-expression, spring-instrument, ...

    spring-web-2.5.jar

    org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer.class org.springframework.web.context.support.ServletContextResource.class org.springframework.web.context.support....

    spring3.1 官方全部jar包

    org.springframework.test-3.1.RELEASE.jar org.springframework.transaction-3.1.RELEASE.jar org.springframework.web.portlet-3.1.RELEASE.jar org.springframework.web.servlet-3.1.RELEASE.jar org.spring...

    org.springframework.context-3.1.0.M1.jar

    org.springframework.context-3.1.0.M1.jar

    spring-framework 源码

    spring-framework源码,已经进行转换 eclipse可直接导入进行分析 包含如下: spring-aop spring-beans spring-aspects spring-context spring-context spring-context-support spring-core spring-expression spring...

    spring3.0.0相关jar包

    org.springframework.test-3.0.0.RELEASE org.springframework.transaction-3.0.0.RELEASE org.springframework.web.portlet-3.0.0.RELEASE org.springframework.web.servlet-3.0.0.RELEASE org.springframework.web...

    spring3.0.2相关jar包

    org.springframework.test-3.0.2.RELEASE org.springframework.transaction-3.0.2.RELEASE org.springframework.web.portlet-3.0.2.RELEASE org.springframework.web.servlet-3.0.2.RELEASE org.springframework.web...

    Spring所需jar包

    org.springframework.test-3.0.0.RELEASE.jar org.springframework.transaction-3.0.0.RELEASE.jar org.springframework.web.portlet-3.0.0.RELEASE.jar org.springframework.web.servlet-3.0.0.RELEASE.jar org....

    spring3.0.5 所有jar文件

    org.springframework.test-3.0.5.RELEASE.jar org.springframework.transaction-3.0.5.RELEASE.jar org.springframework.web-3.0.5.RELEASE.jar org.springframework.web.portlet-3.0.5.RELEASE.jar org.spring...

    spring3.1.1jar及其关联jar

    org.springframework.test-3.1.1.RELEASE org.springframework.transaction-3.1.1.RELEASE org.springframework.web.portlet-3.1.1.RELEASE org.springframework.web.servlet-3.1.1.RELEASE org.springframework.web...

    spring-framework完整源代码(spring框架源码)

    aop,beans,cache,context,core,dao,ejb,instument,jca,jdbc,jms,jmx,jndi,mail,metadate,mock,orm,remoting,scheduling,scripting,stereotype,test,transcation,ui,util,validation,web 以上数十子模块源码全部为...

    spring mvc 3.0.5工程所需包整合

    2.3.0.RELEASE.jar,org.springframework.context.support-3.0.5.RELEASE.jar,org.springframework.context-3.0.5.RELEASE.jar,org.springframework.core-3.0.5.RELEASE.jar,org.springframework.expression-...

    spring-framework-3.0.0.M4-with-docs

    org.springframework.test-3.0.0.M4.jar: spring提供的一个测试框架 org.springframework.jdbc-3.0.0.M4.jar: 对JDBC的简单封装 org.springframework.orm-3.0.0.M4.jar: 整合第三方的ORM框架,如hibernate,...

    spring framework 5 lib.rar

    Spring Framework 开发库, 2019年5月9日最新发布 以下是5.1.7.release, 包括主要组件: spring-aop spring-aspects spring-beans spring-context spring-context-indexer spring-context-support spring-core spring-...

    spring-framework-4.1.6.RELEASE.rar

    spring-test-4.1.6.RELEASE.jar spring-tx-4.1.6.RELEASE.jar spring-web-4.1.6.RELEASE.jar spring-webmvc-4.1.6.RELEASE.jar spring-webmvc-portlet-4.1.6.RELEASE.jar spring-websocket-4.1.6.RELEASE.jar

    spring-framework-4.2.0相关jar

    包含搭建spring相关jar包,aop,core,context,instrument,jdbc,web,test,webmvc等等

    Spring In Action-2.1-01-@Component注解

    package soundsystem; import org.junit.BeforeClass;...public class SpringTest1 { //自动装配 @Autowired private SgtPeppers sp; @Test public void instanceSpring(){ sp.play(); } }

    SpringMVC开发jar包

    org.springframework.test-3.1.0.RELEASE.jar org.springframework.transaction-3.1.0.RELEASE.jar org.springframework.web-3.1.0.RELEASE.jar org.springframework.web.servlet-3.1.0.RELEASE.jar standard.jar

    spring-framework-reference-4.1.2

    3. New Features and Enhancements in Spring Framework 4.0 ............................................ 17 3.1. Improved Getting Started Experience .........................................................

Global site tag (gtag.js) - Google Analytics