欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

大話重構連載15:采用Mock技術完成測試

系統 1640 0
第五次重構我們引入了數據庫的設計,用戶信息要從數據庫中讀取,問候語庫存儲在數據庫中,并支持添加與更新。數據庫的引入使自動化測試變得困難了,因為數據狀態總是變化著的,而這種變化使得測試過程不能復現,這是我們不愿看到的。因此,我們在設計時將業務與數據庫訪問分離,形成了UserDao與GreetingRuleDao。此時,我們的設計應當遵從“依賴反轉”原則,即將UserDao與GreetingRuleDao設計成接口,并編寫它們的實現UserDaoImpl與GreetingRuleDaoImpl。這樣設計就為我們Mock掉UserDao與GreetingRuleDao的實現類創造了條件。

這是我們的設計:


圖4.3 HelloWorld的設計圖


為此,我們編寫了這樣的測試程序:

    	private HelloWorld helloWorld = null;
	private GreetingToUserImpl greetingToUser = null;
	private GreetingAboutTimeImpl greetingAboutTime = null;
	private final static List<GreetingRule> GREETING_RULES = getRules();
	
	/**
	 * @throws java.lang.Exception
	 */
	@Before
	public void setUp() throws Exception {
		helloWorld = new HelloWorld();
		greetingToUser = new GreetingToUserImpl();
		greetingAboutTime = new GreetingAboutTimeImpl();
		helloWorld.setGreetingToUser(greetingToUser);
		helloWorld.setGreetingAboutTime(greetingAboutTime);
	}
	
	/**
	 * @throws java.lang.Exception
	 */
	@After
	public void tearDown() throws Exception {
		helloWorld = null;
		greetingToUser = null;
		greetingAboutTime = null;
	}

	/**
	 * Test method for {@link org...HelloWorld#sayHello(java.util.Date, java.lang.String)}.
	 */
	@Test
	public void testSayHelloInTheMorning() {
		final Date now = DateUtil.createDate(2013, 9, 7, 9, 23, 11);
		final long userId = 2013090701;
		
		UserDao userDao = createMock(UserDao.class);
		GreetingRuleDao greetingRuleDao = createMock(GreetingRuleDao.class);
		expect(userDao.loadUser(userId)).andAnswer(new IAnswer<User>(){
			@Override
			public User answer() throws Throwable {
				User user = new User();
				user.setUserId(userId);
				user.setName("鮑曉妹");
				return user;
			}});
		expect(greetingRuleDao.findAllGreetingRules())
		.andAnswer(new IAnswer<List<GreetingRule>>(){
			@Override
			public List<GreetingRule> answer() throws Throwable {
				return GREETING_RULES;
			}});
		replay(userDao);
		replay(greetingRuleDao);
		
		greetingToUser.setUserDao(userDao);
		greetingAboutTime.setGreetingRuleDao(greetingRuleDao);
		
		String result = helloWorld.sayHello(now, userId);
		Assert.assertEquals("Hi, 鮑曉妹. Good morning!", result);
		verify(userDao);
		verify(greetingRuleDao);
	}
  


這段測試程序比較長,但其它部分都是打醬油的,核心是那個testSayHelloInTheMorning()用例,即問候早上好這個用例。userDao與greetingRuleDao是兩個接口,我們在實例化它們的時候,并沒有去創建它們的實現類,而是用Mock的方式進行創建:

    	UserDao userDao = createMock(UserDao.class);
	GreetingRuleDao greetingRuleDao = createMock(GreetingRuleDao.class);
  


隨后我們開始定義它們的行為loadUser()與getAllGreetingRules()。在這個測試用例中,我們并不關心它們是怎樣去數據庫里查詢數據并返回的,我們只關心它們是否得到應該得到的參數,并要求它們按照規定返回一個結果:

    	final long userId = 2013090701;
	expect(userDao.loadUser(userId)).andAnswer(new IAnswer<User>(){
			@Override
			public User answer() throws Throwable {
				User user = new User();
				user.setUserId(userId);
				user.setName("鮑曉妹");
				return user;
			}});
  



我們希望被測程序在執行的時候調用了userDao.loadUser(userId),并且調用時傳入的參數userId = 2013090701。如果測試過程中傳入的參數是這個值,這一項檢查點可以通過,否則不能通過。隨后我們希望該函數返回“鮑曉妹”這個用戶對象。通過Mock程序,我們完全將數據庫訪問的過程剝離在自動化測試之外,而只是驗證它的輸入參數,并指定測試所需的返回結果。也就是說數據訪問過程被Mock掉,而大大降低了測試難度。

如果UserDao與GreetingRuleDao的Mock程序不能得到規定的參數時,測試就不能通過,這就是說傳遞給Mock程序的參數也成為了測試程序要驗證的一個輸出。隨后,Mock程序返回規定值,該規定值則成為了被測程序的一個輸入。最后,被測程序根據這個輸入返回結果,為測試程序所驗證,測試結束(如圖4.4所示)。


圖4.4 HelloWorld的自動化測試


圖中的BUS層才是我們大量編碼,應當自動化測試的部分。既然是測試就是驗證怎樣的輸入,應當得到怎樣的輸出。Web層向BUS層發出的請求,即調用BUS層某個類的方法,就是測試用例中的一個輸入,執行完該方法后的返回值就是測試用例的一個輸出。但是,這對輸入輸出并不是該測試用例的全部。這里經過BUS層處理以后,經過一系列的邏輯判斷和數據操作,隨后會去調用DAO層進行數據訪問操作。調用DAO層時所傳遞的參數,就是測試用例的另一個輸出。圖中,從DAO層的輸入,到它的輸出,這段數據庫訪問的過程被Mock程序Mock掉了,因為它不在這個用例的測試范圍。然后DAO層返回給BUS層一個結果,該結果就是測試用例的另一個輸入。接著BUS層會再次對這個返回結果進行處理,最后返回給Web層最終的結果。這就是采用Mock方式進行自動化測試的一個完整流程。

采用自動化測試,測試程序將不再驗證后臺的數據庫是否正確,同時也不再驗證前臺的Web應用及其前端設備是否正確。在該例中,系統的真正目的是要在前臺顯示對用戶的問候,因此將會有一個Action或Servlet調用HelloWorld:

    	Date now = DateUtil.getNow();
	String user = SessionUtil.getCurrentUser(session);
	HelloWorld helloWorld = new HelloWorld();
	String greeting = helloWorld.sayHello(now, user);
	request.setAttribute(“greeting”, greeting);
  


然而,這些程序都不適合自動化測試而應采用手工測試。回顧HelloWorld自動化測試建立的過程我們不難發現,它在設計之初就實現了業務邏輯與Web應用、與數據訪問的分離,所以它可以輕易的建立自動化測試。但是,不幸的是,我們大多數的遺留系統在設計之初都沒有考慮到這些。因此,我說,在重構之初首先建立自動化測試機制是不現實的,我們只能采用手工測試結合QTP的方式。只有當我們通過重構,使系統架構滿足自動化測試的條件之后,自動化測試才可以開展。

毫無疑問,測試與重構形成了一個“雞生蛋,還是蛋生雞”的怪圈,成為我們實踐系統重構一大攔路虎。本書將在后面詳細討論這個話題(詳見 第十六章 測試的困境),為你破解這個謎團。

大話重構連載首頁: http://fangang.iteye.com/blog/2081995
特別說明:希望網友們在轉載本文時,應當注明作者或出處,以示對作者的尊重,謝謝!

大話重構連載15:采用Mock技術完成測試


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 国产一区二区精品在线观看 | xifan在线a精品一区二区视频网站 | 国产青青 | 91视频免费网址 | 国产大片91精品免费看3 | 天天综合色天天综合 | 欧美一区二区三区播放 | 日日a.v拍夜夜添久久免费 | 一级特黄录像视频免费 | 免费一级毛片不卡不收费 | 一级特黄录像视频免费 | 亚洲91在线 | 91传媒蜜桃香蕉在线观看 | 欧洲一级毛片 | 欧美久久久久久 | 6全高清智能录播系统视频 精品九九 | 毛片24种姿势无遮无栏 | 国产成人一区二区三区电影 | 瑟瑟网站免费网站入口 | 在线视频综合视频免费观看 | 亚洲欧美第一页 | 精品国产精品久久 | 色免费视频 | 99久久精品国产导航 | 最新欧美精品一区二区三区 | 中文字幕国产一区 | 91看片在线观看 | 国产福利99| 一级欧美黄色片 | 欧美最新一区二区三区四区 | 欧美丰满丝袜videossex | 日韩大尺度电影在线观看 | 在线观看www | 日韩精品一区二区三区中文字幕 | 色婷婷.com| 波多久久夜色精品国产 | 日韩色小说 | 亚洲欧美日韩精品久久亚洲区 | 亚洲日韩精品AV无码富二代 | 天堂网果冻传媒 | 中文字幕一区二区精品区 |