對程序進行單元測試時,有時我們會遇到一些小麻煩,比如某些操作十分耗時,有些依賴的對象不易獲取等等,這時我們就可以通過Groovy Mock或Groovy Stub來解決這些問題。Mock對方法調用的次數十分敏感,如果程序中調用的次數不在期望的調用次數范圍內,則會拋出異常以致測試失敗;而Stub僅僅是起到‘替身’的作用,它并不關心方法調用與否,即使方法一次都沒被調用,也不會拋出異常導致測試失敗。
下面讓我們來看一個實際的例子吧:
import?groovy.mock.interceptor.*
class?User?{
????String?name
????String?address
????String?toString()?{
????????"Name:?$name,?Address:?$address"
????}
}
class?UserDao?{
????User?findUserByName(String?name)?{
????????if?('山風小子'?==?name)
????????????return?new?User(name:name,?address:'Shanghai')
????????else
????????????return?new?User(name:'Anonymous?User',?address:'Unknown')
????}
}
class?ShowUserInfoService?{
????UserDao?userDao?=?new?UserDao()
????def?showInfo(String?name)?{
????????User?user?=?userDao.findUserByName('山風小子')
????????println?user
????}
}
/*
??? 平時下面這些代碼寫于單元測試中,為了簡潔起見,單獨抽取出來
*/
def?userDaoMock?=?new?MockFor(UserDao)
/*
????UserDao對象中的findUserByName方法必須被調用1~2次,否則測試失敗
????同時將findUserByName方法的實現替換為return?new?User(name:'mock?user',?address:'Unknown')
*/
userDaoMock.demand.findUserByName(1..2)?{?String?name?->
????return?new?User(name:'mock?user',?address:'Unknown')
}
userDaoMock.use?{
????def?showUserInfoService?=?new?ShowUserInfoService()
????showUserInfoService.showInfo('山風小子')
????showUserInfoService.showInfo('Daniel.Sun')
????//showUserInfoService.showInfo('BlueSUN')
}
def?userDaoStub?=?new?StubFor(UserDao)
/*
????僅僅將findUserByName方法的實現替換為return?new?User(name:'stub?user',?address:'Unknown')
????即使findUserByName方法不被調用,測試也不會失敗
*/
userDaoStub.demand.findUserByName?{?String?name?->
????return?new?User(name:'stub?user',?address:'Unknown')
}
userDaoStub.use?{
????def?showUserInfoService?=?new?ShowUserInfoService()
????showUserInfoService.showInfo('山風小子')
}
運行結果:
Name:?mock?user,?Address:?Unknown
Name:?mock?user,?Address:?Unknown
Name:?stub?user,?Address:?Unknown
附:
朝花夕拾——Groovy & Grails
posted on 2008-06-13 23:25
山風小子 閱讀(4022)
評論(2) 編輯 收藏 所屬分類:
Groovy & Grails