Spring2.5+JUnit4單元測試
要求:
JDK1.5以上(因為Junit4是用注解來實現的)
需要的包
spring-2.5.jar
junit-4.4.jar
spring-test.jar
測試類
package user; import static org.junit.Assert.fail; import java.util.Date; import org.junit.After; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.annotation.Rollback; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests; import org.springframework.test.context.transaction.TransactionConfiguration; import com.sample.model.user.User; import com.sample.service.user.IUserService; /** 設置要加載的配置文件 */ @ContextConfiguration( locations={ "classpath:spring/persistenceContext.xml", "classpath:spring/aopContext.xml", "classpath:spring/daoContext.xml", "classpath:spring/serviceContext.xml" } ) /** 設置是否回滾數據 */ @TransactionConfiguration(defaultRollback = false) public class UserTest extends AbstractTransactionalJUnit4SpringContextTests{ /** 設置自動注入的屬性 */ @Autowired private IUserService userService; @Before public void setUp() throws Exception { } @After public void tearDown() throws Exception { } @Test @Rollback(false) public void testSaveUser() { User user=new User(); user.setUsername("zhoujun"); user.setCreatetime(new Date()); userService.saveUser(user); } @Test public void testGetUserById() { User user=userService.getUserById("1"); System.out.println(user.getUsername()); System.out.println(user.getCreatetime()); } } |
有關Junit4中注解的說明如下:
@ContextConfiguration 用來指定加載的Spring配置文件的位置,會加載默認配置文件
例如下例會加載:classpath:/com/example/MyTest-context.xml文件
package com.example; @ContextConfiguration public class MyTest { // class body... } @ContextConfiguration 注解有以下兩個常用的屬性: locations:可以通過該屬性手工指定 Spring 配置文件所在的位置,可以指定一個或多個 Spring 配置文件。如下所示: @ContextConfiguration(locations={“xx/yy/beans1.xml”,” xx/yy/beans2.xml”}) inheritLocations:是否要繼承父測試用例類中的 Spring 配置文件,默認為 true。如下面的例子: @ContextConfiguration(locations={"base-context.xml"}) public class BaseTest { // ... } @ContextConfiguration(locations={"extended-context.xml"}) public class ExtendedTest extends BaseTest { // ... } |
如果 inheritLocations 設置為 false,則 ExtendedTest 僅會使用 extended-context.xml 配置文件,否則將使用 base-context.xml 和 extended-context.xml 這兩個配置文件。
在使用所有注釋前必須使用@RunWith(SpringJUnit4ClassRunner.class),讓測試運行于Spring測試環境
Spring框架在org.springframework.test.annotation 包中提供了常用的Spring特定的注解集,如果你在Java5或以上版本開發,可以在測試中使用它。
@IfProfileValue
提示一下,注解測試只針對特定的測試環境。 如果配置的ProfileValueSource類返回對應的提供者的名稱值, 這個測試就可以啟動。這個注解可以應用到一個類或者單獨的方法。
@IfProfileValue(name=”java.vendor”, value=”Sun Microsystems Inc.”)
public void testProcessWhichRunsOnlyOnSunJvm() {
// some logic that should run only on Java VMs from Sun Microsystems
}
同時@IfProfileValue可配置一個值列表 (使用OR 語義) 來在JUnit環境中獲得TestNG的測試組支持。 看下面的例子:
@IfProfileValue(name=”test-groups”, values={”unit-tests”, “integration-tests”})
public void testProcessWhichRunsForUnitOrIntegrationTestGroups() {
// some logic that should run only for unit and integration test groups
}
@ProfileValueSourceConfiguration
類級別注解用來指定當通過@IfProfileValue注解獲取已配置的profile值時使用何種ProfileValueSource。 如果@ProfileValueSourceConfiguration沒有在測試中聲明,將默認使用SystemProfileValueSource。
@ProfileValueSourceConfiguration(CustomProfileValueSource.class)
public class CustomProfileValueSourceTests {
// class body…
}
@DirtiesContext
在測試方法上出現這個注解時,表明底層Spring容器在該方法的執行中被“污染”,從而必須在方法執行結束后重新創建(無論該測試是否通過)。
@DirtiesContext
public void testProcessWhichDirtiesAppCtx() {
// some logic that results in the Spring container being dirtied
}
@ExpectedException
表明被注解方法預期在執行中拋出一個異常。預期異常的類型在注解中給定。如果該異常的實例在測試方法執行中被拋出, 則測試通過。同樣的如果該異常實例沒有在測試方法執行時拋出,則測試失敗。
@ExpectedException(SomeBusinessException.class)
public void testProcessRainyDayScenario() {
// some logic that should result in an Exception being thrown
}
@Timed
表明被注解的測試方法必須在規定的時間區間內執行完成(以毫秒記)。如果測試執行時間超過了規定的時間區間,測試就失敗了。
注意該時間區間包括測試方法本身的執行,任何重復測試(參見 @Repeat),還有任何測試fixture的set up或tear down時間。
Spring的@Timed注解與JUnit 4的@Test(timeout=...)支持具有不同的語義。 特別地,鑒于JUnit 4處理測試執行超時(如通過在一個單獨的線程中執行測試方法)的方式, 我們不可能在一個事務上下文中的測試方法上使用JUnit的@Test(timeout=...)配置。因此, 如果你想將一個測試方法配置成計時且具事務性的, 你就必須聯合使用Spring的@Timed及@Transactional注解。 還值得注意的是@Test(timeout=...)只管測試方法本身執行的次數,如果超出的話立刻就會失敗; 然而,@Timed關注的是測試執行的總時間(包括建立和銷毀操作以及重復),并且不會令測試失敗。
@Timed(millis=1000)
public void testProcessWithOneSecondTimeout() {
// some logic that should not take longer than 1 second to execute
}
@Repeat
表明被注解的測試方法必須重復執行。執行的次數在注解中聲明。
注意重復執行范圍包括包括測試方法本身的執行,以及任何測試fixture的set up或tear down。
@Repeat(10)
public void testProcessRepeatedly() {
// …
}
@Rollback
表明被注解方法的事務在完成后是否需要被回滾。 如果true,事務將被回滾,否則事務將被提交。 使用@Rollback接口來在類級別覆寫配置的默認回滾標志。
@Rollback(false) public void testProcessWithoutRollback() { // … } @NotTransactional 出現該注解表明測試方法必須不在事務中執行。 @NotTransactional public void testProcessWithoutTransaction() { // … } Spring TestContext Framework還支持下面這些非特定于測試的注解,并且保持其語義不變。 @Autowired @Qualifier @Resource (javax.annotation)如果JSR-250可用 @PersistenceContext (javax.persistence)如果JPA可用 @PersistenceUnit (javax.persistence)如果JPA可用 @Required @Transactional @TestExecutionListeners |
定義類級別的元數據,TestExecutionListeners會使用TestContextManager進行注冊。 通常,@TestExecutionListeners與@ContextConfiguration會搭配使用。
@ContextConfiguration @TestExecutionListeners({CustomTestExecutionListener.class, AnotherTestExecutionListener.class}) public class CustomTestExecutionListenerTests { // class body... } |
@TransactionConfiguration
為配置事務性測試定義了類級別的元數據。特別地,如果需要的PlatformTransactionManager不是“transactionManager”的話, 那么可以顯式配置驅動事務的PlatformTransactionManager的bean名字。此外, 可以將defaultRollback標志改為false。通常, @TransactionConfiguration與@ContextConfiguration搭配使用。
@ContextConfiguration @TransactionConfiguration(transactionManager="txMgr", defaultRollback=false) public class CustomConfiguredTransactionalTests { // class body... } @BeforeTransaction 表明被注解的public void方法應該在測試方法的事務開始之前執行, 該事務是通過@Transactional注解來配置的。 @BeforeTransaction public void beforeTransaction() { // logic to be executed before a transaction is started } @AfterTransaction 表明被注解的public void方法應該在測試方法的事務結束之后執行, 該事務是通過@Transactional注解來配置的。 @AfterTransaction public void afterTransaction() { // logic to be executed after a transaction has ended } |
posted on 2014-06-05 13:44 順其自然EVO 閱讀(321) 評論(0) 編輯 收藏 所屬分類: 測試學習專欄