在
ecipse
里
Spring
框架中進行
JUnit
單元測試
?
測試對于保證軟件開發質量有著非常重要的作用,單元測試更是必不可少,
JUnit
是一個非常強大的單元測試包,可以對一個
/
多個類的單個
/
多個方法測試,還可以將不同的
TestCase
組合成
TestSuit
,使測試任務自動化。
Eclipse
同樣集成了
JUnit
,可以非常方便地編寫
TestCase
。
一、????????????
JUnit
核心
JUnit
的目的是協助您進行單元測試(
Unit Test
),并鼓勵您先寫測試。
JUnit
包括了以下的特性:
對預期結果作斷言
提供測試裝備的生成與銷毀
易于組織與執行測試
圖型與文字介面的測試器
?
JUnit
的核心類:TestCase、TestSuite以及BaseTestRunner,其中用的最多的就是TestCase,當需要多個TestCase的時候就要創建一個TestSuite,而運行TestSuite則要創建TestRunner,其關系如下:
核心類定義:
??????? TestCase
(測試用例)
——
擴展了JUnit的TestCase類的類。它以testXXX方法的形式包含一個或多個測試。一個test case把具有公共行為的測試歸入一組。在本書的后續部分,當我們提到測試的時候,我們指的是一個testXXX方法;當我們提及test case的時候,我們指的是一個繼承自TestCase的類,也就是一組測試。
???????TestSuite
(測試集合
)——一組測試。一個test suite是把多個相關測試歸入一組的便捷方式。例如,如果你沒有為TestCase定義一個test suite,那么JUnit就會自動提供一個test suite,包含TestCase中所有的測試(本書稍后會細說)。
????????TestRunner
(測試運行器
)——執行test suite的程序。JUnit提供了幾個test runner,你可以用它們來執行你的測試。沒有TestRunner接口,只有一個所有test runner都繼承的BaseTestRunner。因此,當我們編寫TestRunner的時候,我們實際上指的是任何繼承BaseTestRunner的test runner類。
其中TesetCase主要有10個自己的方法:
?
二、下面就以Eclipse中單個TestCase為例子講一下普通的JUnit測試:
???
首先我們創建一個
Java
工程,添加一個
example.Hello
類,首先我們給
Hello
類添加一個
abs()
方法,作用是返回絕對值:
下一步,我們準備對這個方法進行測試,確保功能正常。選中
Hello.java
,右鍵點擊,選擇
New->JUnit Test Case
:
Eclipse
會詢問是否添加
junit.jar
包,確定后新建一個
HelloTest
類,用來測試
Hello
類。
選中
setUp()
和
tearDown()
,然后點擊
“Next”
:
選擇要測試的方法,我們選中
abs(int)
方法,完成后在
HelloTest.java
中輸入:
JUnit
會以以下順序執行測試:(大致的代碼)
try { HelloTest test = new HelloTest(); //
建立測試類實例
test.setUp(); //
初始化測試環境
test.
testAbs
(); //
測試某個方法
test.tearDown(); //
清理資源
} catch…
|
setUp()
是建立測試環境,這里創建一個
Hello
類的實例;
tearDown()
用于清理資源,如釋放打開的文件等等。以
test
開頭的方法被認為是測試方法,
JUnit
會依次執行
testXxx()
方法。在
testAbs()
方法中,我們對
abs()
的測試分別選擇正數,負數和
0
,如果方法返回值與期待結果相同,則
assertEquals
不會產生異常。
如果有多個
testXxx
方法,
JUnit
會創建多個
XxxTest
實例,每次運行一個
testXxx
方法,
setUp()
和
tearDown()
會在
testXxx
前后被調用,因此,不要在一個
testA()
中依賴
testB()
。
直接運行
Run->Run As->JUnit Test
,就可以看到
JUnit
測試結果:
綠色表示測試通過,只要有
1
個測試未通過,就會顯示紅色并列出未通過測試的方法。可以試圖改變
abs()
的代碼,故意返回錯誤的結果(比如
return n+1;
),然后再運行
JUnit
就會報告錯誤。
三、在
Spring
中進行
DAO
測試
???
Spring
提供了下列一些特定的JUnit框架擴展:
AbstractDependencyInjectionSpringContextTests—
這是一個針對所有測試的超類,其具體使用依賴于Spring上下文。
AbstractSpringContextTests—
這是一個針對所有的JUnit測試情形的超類。它使用一個Spring上下文。并且,一般在測試中不是直接使用它,而是使用AbstractDependencyInjectionSpringContextTests或者AbstractTransactionalSpringContextTests這樣的派生類。
AbstractTransactionalSpringContextTests—
這是一個針對所有測試的超類,我們一般把它應用在事務相關的測試中。注意,一旦完成每個測試它就會正常地回滾事務;而且你需要重載onSetUpInTransaction和onTearDownInTransaction方法以便手工開始并提交事務。
AbstractTransactionalDataSourceSpringContextTests—
這是AbstractTransactionalSpringContextTests的一個子類,它使用了Spring的基于JDBC的jdbcTemplate工具類。
所有上面這些擴展將極大程度地簡化在測試時對于相關操作的依賴性注入和事務管理。
??????
下面就以一個用戶
DAO
類
HibernateUserDao
類中的一個方法
getPasswordByName(String userName)
進行測試作為例子,其中的輸入就是用戶名,輸出就是用戶密碼:
測試類:
//HibernateUserDAOTest.java
public
class
HibernateUserDAOTest
extends
AbstractTransactionalDataSourceSpringContextTests
{
??? ApplicationContext
applicationContext
;
??? HibernateUserDAO
hub
;
???
???
@Override
???
protected
String[] getConfigLocations()
??? {
?????? String[] config=
new
String[]{
"file:D:\\RfidStock2\\WebRoot\\WEB-INF\\classes\\applicationContext.xml"
};
??????
return
config;
??? }
???
???
public
ApplicationContext getContext(String[] filePath)
??? {
?
??????
return
new
ClassPathXmlApplicationContext(filePath);
??? }
???
??????
???
public
void
testConfig() {???????
???????
assertNotNull(
"spring-mock context has bean init()"
,
this
.getConfigLocations());
??? }
???
???
???
???
@Test
???
public
final
void
testGetPasswordByName()
throws
BaseException
??? {
??????
hub
=(HibernateUserDAO)getContext(getConfigLocations()).getBean(
"hibernateUserDAO"
);
??????
assertEquals(
"234"
,
hub
.
getPasswordByName
(
"42"
));
??? }
???
???
public
static
void
main(String[] args)
??? {
?????? TestRunner.run((Class<?
extends
TestCase>) HibernateUserDAO.
class
);
??? }
???
}
在
Spring
下由于要驅動
Spring
,所以測試類要繼承
AbstractTransactionalDataSourceSpringContextTests
類,需要實現一個方法
String[] getConfigLocations()
,用這個方法來獲取
Spring
的配置文件,然后我通過寫
getContext(String[] filePath)
這個方法來獲取
Spring
的上下文,在這里我們要獲取待測試對象有兩種方法一種就是
setHibernateUserDAO()
和
getHibernateUserDAO()
方法,另外一種就是通過上下文提取配置文件中定義的
Bean
,然后再獲取具體的方法。
這個就是測試結果: