2009年12月17日 星期四

Spring單元測試一點筆記

前一陣子去參加OSSF的Annotation講座
裡面有提到JUnit4作單元測試

下面一個參考網站
http://liyiye.javaeye.com/blog/443239

以往作單元測試的時候都必須去繼承TestCase類別
這無疑阻礙了測試程式的設計,但是使用Annotation為基礎作Unit test的話
不只函式名稱不用被綁死,在設計上也更簡單



順便把OSSF的一個傳統TestCase例子附上


public class MyCalculatorTest extends TestCase {

private MyCalculator cal ;

public void setUp() throws Exception {
System.out.println("Begin test....");
cal = new MyCalculator();
}

public void tearDown() throws Exception {
cal = null;
System.gc();
System.out.println("End test....");
}

public void testSum() { // Test Method should be begin with test*()
int sum = cal.sum(1, 3);
assertEquals(4, sum);
}

public void testSub() {
int sub = cal.sub(3, 1);
assertEquals(-2, sub);
}

}


再來比較一個JUnit4作單元測試的case

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"spring-test.xml"})

public class UserServiceTest {

@Autowired
MyServer myserService;

@Test
public void testService(){
myserService.say();
Assert.assertNotNull(myserService);
}
}

不用再去繼承什麼東西,只要Annotation加註就可以進行單元測試,只要有@Test標記的函式就代表他是個要做測試的函式,名稱也不用被綁定test開頭,不過我這裡就習慣性的先用同樣的命名

而要注意的是上方兩個Annotation,@RunWith@ContextConfiguration,前者代表指定要跑的類別,在此就是Junit4,後者則是要測試的Test class所在位置的config檔

下面放上config檔內容

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"
default-autowire="byName">

<context:annotation-config/>
<context:component-scan base-package="org.cusano">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>
</context:component-scan>


</beans>



重點是base-package="org.cusano"這段,要指出你的測試類別所在package,我是放在org.cusano之下

不過執行的時候卻跑出一個錯誤


Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory


後來上網查了一下是缺少commons-logging.jar,他通常都是在tomcat的安裝目錄下
以我的版本為例,他在tomcat50-jwsdp\bin這個目錄之下 並且叫做commons-logging-api.jar
名稱有些不一樣,不過沒關係,找的到就好。之後就可以開始作單元測試了

而JUnit4的Annotation除了@Test,@Rollback之外。還有@Before@After
@Before主要是在測試開始前要做得一些事情,假設有些測試物件產生要花很多時間,就可以放在@Befor標住的函式去做,@After則是測試結束後要做的事情,可以做些資源釋放的動作。
一樣放個OSSF講義上的例子

public class MyCalculatorTest {

private MyCalculator cal ;
@Before
public void setUp() throws Exception { // You can change method name as you wish for tearDown
System.out.println("Begin test....");
cal = new MyCalculator();
}
@After
public void tearDown() throws Exception { // You can change method name as you wish for tearDown
cal = null;
System.gc();
System.out.println("End test....");
}
@Test
public void testSum() { // You can change method name as you wish for testSum
int sum = cal.sum(1, 3);
assertEquals(4, sum);
}
@Test
public void testSub() { // You can change method name as you wish for testSub
int sub = cal.sub(3, 1);
assertEquals(-2, sub);
}

}


沒有留言: