與JodaTime的DateTime和Google Guava的供應商嘲笑

介紹

如果您是經驗豐富的單元測試人員,那么當您看到任何與時間并發性隨機性持久性磁盤I / O協同工作的代碼時,您就會學會做筆記。

原因是測試可能非常脆弱,有時完全無法正確測試。 這篇文章將展示如何通過向消費者注入替代品來提取“時間”。 這篇文章將使用Spring 3作為Dependency Injection容器,盡管Guice ,其他DI容器或POJO上的構造器/設置器也可以使用。 我也將忽略Locales,因為重點在于DateTime的注入,而不是DateTime本身。

現有代碼

您已經獲得了一段代碼進行單元測試(或者您正在創建一個代碼,這是您的第一次嘗試)。 我們的第一段代碼,只有一個類:(該類是Spring 3.1控制器,其目的是作為String返回當前時間)

@Controller
@RequestMapping(value = '/time')
@VisibleForTesting
class TimeController {@RequestMapping(value = '/current', method = RequestMethod.GET)@ResponseBodypublic String showCurrentTime() {// BAD!!! Can't testDateTime dateTime = new DateTime();return DateTimeFormat.forPattern('hh:mm').print(dateTime);}
}

請注意,該類在該類中執行“新的DateTime()”。 這是相應的測試類:

我們進行測試會怎樣? 假設我們有一臺非常慢的機器怎么樣。 您可能(并且很可能會)以比較DateTime與返回的DateTime不同 。 這是個問題!

首先要做的是刪除依賴關系,但是我們該怎么做呢? 如果我們將DateTime設置為類的一個字段,我們仍然會遇到同樣的問題。 介紹Google Guava的供應商界面。

Google Guava供應商

Supplier接口只有一個方法“ get()”,它將返回設置了任何供應商的實例。 例如,如果用戶已登錄,則供應商將返回用戶的名字,如果尚未登錄,則返回默認用戶名:

public class FirstNameSupplier implements Supplier<String> {private String value;private static final String DEFAULT_NAME = 'GUEST';public FirstNameSupplier() {// Just believe that this goes and gets a User from somewhereString firstName = UserUtilities.getUser().getFirstName();// more Guavaif(isNullOrEmpty(firstName)) {value = DEFAULT_NAME;} else {value = firstName;}}@Overridepublic String get() {return value;}
}

對于您的實現方法,您并不在乎名字是什么,而只是得到一個名字。

重構DateTime

讓我們繼續。 有關使用Supplier的更真實的示例(以及本文的要點),讓我們實現一個DateTime供應商,以將當前的DateTime還給我們。 在此過程中,我們還創建一個接口,以便我們可以創建模擬實現以進行測試:

public interface DateTimeSupplier extends Supplier<DateTime> {DateTime get();
}

一個實現:

public class DateTimeUTCSupplier implements DateTimeSupplier {@Overridepublic DateTime get() {return new DateTime(DateTimeZone.UTC);}
}

現在,我們可以使用DateTimeUTCSupplier并將其注入需要當前DateTime作為DateTimeSupplier接口的代碼中:

@Controller
@RequestMapping(value = '/time')
@VisibleForTesting
class TimeController {@Autowired@VisibleForTesting// Injected DateTimeSupplierDateTimeSupplier dateTime;@RequestMapping(value = '/current', method = RequestMethod.GET)@ResponseBodypublic String showCurrentTime() {return DateTimeFormat.forPattern('hh:mm').print(dateTime.get());}
}

為了測試這一點,我們需要創建一個MockDateTimeSupplier并有一個控制器傳遞要返回的特定實例:

public class MockDateTimeSupplier implements DateTimeSupplier {private final DateTime mockedDateTime;public MockDateTimeSupplier(DateTime mockedDateTime) {this.mockedDateTime = mockedDateTime;}@Overridepublic DateTime get() {return mockedDateTime;}
}

請注意,要保存的對象是通過構造函數傳遞的。 這不會使您獲得當前的日期/時間,但是會返回您想要的特定實例

最后是我們的測試(略微)行使了我們上面實現的TimeController的測試:

public class TimeControllerTest {private final int HOUR_OF_DAY = 12;private final int MINUTE_OF_DAY = 30;@Testpublic void testShowCurrentTime() throws Exception {TimeController controller = new TimeController();// Create the mock DateTimeSupplier with our known DateTimecontroller.dateTime = new MockDateTimeSupplier(new DateTime(2012, 1, 1, HOUR_OF_DAY, MINUTE_OF_DAY, 0, 0));// Call our methodString dateTimeString = controller.showCurrentTime();// Using hamcrest for easier to read assertions and condition matchersassertThat(dateTimeString, is(String.format('%d:%d', HOUR_OF_DAY, MINUTE_OF_DAY)));}}

結論

這篇文章展示了如何使用Google Guava的Supplier接口抽象出DateTime對象,以便您在考慮單元測試的情況下更好地設計實現! 供應商是解決“只給我一些東西”的好方法,請注意,這是已知的某種東西。

祝您編程愉快,別忘了分享!

參考:在Mike的網站博客上,從我們的JCG合作伙伴 Mike 嘲笑JodaTime的DateTime和Google Guava的供應商 。


翻譯自: https://www.javacodegeeks.com/2012/10/mocking-with-jodatimes-datetime-and.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/371020.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/371020.shtml
英文地址,請注明出處:http://en.pswp.cn/news/371020.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

棧實現 C語言

最近上來寫了一下棧&#xff0c;理解數據結構的棧。 頭文件&#xff1a;stack.h 初始化棧結構與函數定義&#xff1a; #include<stdlib.h> #include <stdio.h> #include<memory.h> #define N 100struct stack {int data[N];int top;//標識棧頂 }; typedef s…

php簽名墻,肺功能檢查質量控制網

2017年12月2日&#xff0c;由中華醫學會呼吸病學分會/兒科分會、國家呼吸系統疾病臨床醫學研究中心、國家呼吸疾病醫療質量控制中心、中國肺功能聯盟、中國兒童肺功能協作組主辦&#xff0c;浙江省中醫院承辦的"2017年中國肺功能檢查規范化培訓及應用推廣學習班暨肺功能檢…

餐飲水單打印軟件_開發一款餐飲手機app系統軟件什么價格?有哪些方面需要考慮?...

開發一款餐飲手機app系統軟件什么價格&#xff1f;有哪些方面需要考慮&#xff1f;近年來&#xff0c;餐飲類的APP如雨后春筍般快速增長&#xff0c;無論是上檔次的酒店&#xff0c;還是各大餐廳&#xff0c;都有各自的專屬APP。餐飲APP的開發能讓大型酒店/餐廳獲得更多盈利、銷…

html5中如何去掉input type date默認

html5中如何去掉input type date默認樣式 2.對日期時間控件的樣式進行修改目前WebKit下有如下9個偽元素可以改變日期控件的UI&#xff1a;::-webkit-datetime-edit – 控制編輯區域的::-webkit-datetime-edit-fields-wrapper – 控制年月日這個區域的::-webkit-datetime-edit-…

Spring-framework應用程序啟動loadtime源碼分析筆記(二)——@Transactional

Transactional標識類或方法&#xff0c;使方法被執行時使用事務方式執行&#xff0c;這里只討論PROXY方法增強方法。使用EnableTransactionManagement&#xff0c;默認modelAdviceMode.PROXY&#xff0c;通過Import(TransactionManagementConfigurationSelector.class)來判斷在…

具有Spring的簡單工作流引擎

幾個月前&#xff0c;在處理一個公司項目時&#xff0c;我們需要開發REST服務&#xff0c;該服務用于根據客戶端應用程序發送的數據發送電子郵件。 在開發此服務期間&#xff0c;我們決定創建簡單的工作流引擎&#xff0c;該引擎將為發送電子郵件收費&#xff0c;但該引擎也可用…

php put 參數,php – 如何在Guzzle 5中發送PUT請求的參數?

根據the manual,The body option is used to control the body of an entity enclosingrequest (e.g., PUT, POST, PATCH).記錄的put’ing方法是&#xff1a;$client new GuzzleHttp\Client();$client->put(http://httpbin.org, [headers > [X-Foo > Bar],body > …

TypeScript學習筆記歸納(持續更新ing)

文章目錄 前言 二、TypeScript的優勢體現在哪里&#xff1f; 1、執行時間上的區別 2、基礎數據類型區別 3、TS優勢 三、TypeScript的關鍵特性 四、TypeScript的類型系統 1、什么是類型注釋&#xff1f; 2、類型系統核心 - 常用類型 1&#xff09; 基本類型&#xff0…

組態王 6.55 啟停plc_永宏PLC在遠程控制系統中的應用

一、行業介紹本遠程控制系統是給石藥集團的下屬子公司設計的一個控制方案。主要是配套GPRS-DTU產品實現遠程plc與plc之間的數據共享。從而達到遠程無線數據寫入控制和讀取監控的目的。二、客戶需求(1) 客戶可以在監控室控制至少2-3公里外的井上兩個水泵的啟動和停止。(2) 客戶可…

Vue表格中,對數據進行轉換、處理

眾所周知&#xff0c;后端從Mysql取出的數據&#xff0c;一般是很難單獨處理某一個Key的數據的&#xff08;需要處理的話&#xff0c;可能會浪費大量的性能。而且對頁面加載時間有很大的影響&#xff09;&#xff0c;所以&#xff0c;從數據庫取出的數據。只能由前端進行處理。…

Java應用程序中的SQL注入

在本文中&#xff0c;我們將討論什么是SQL注入攻擊。 以及它如何影響任何Web應用程序使用后端數據庫。 在這里&#xff0c;我專注于Java Web應用程序。 開放Web應用程序安全項目&#xff08;OWAP&#xff09;列出了SQL注入是Web應用程序的主要漏洞攻擊。 黑客將Web請求中的SQL代…

【轉】ReactNativeweexDeviceOne對比

React Native出來有一段時間了&#xff0c;國內的weex和deviceone是近期發布的&#xff0c;我可以說從2011年就開始關注快速開發的跨平臺平臺技術了&#xff0c;接觸過phoneGap、數字天堂、appcan等早期的移動中間件技術&#xff0c;也跟朋友也討論過這類的輕量級框架。這些年通…

bluetooth射頻已關閉請打開bluetooth射頻_希杰大功率射頻放大器燒了維修診斷步驟...

如果電阻值過低&#xff0c;說明電源內部存在短路&#xff0c;正常時其阻值應能達到100千歐以上;電容器應能夠充放電&#xff0c;如果損壞&#xff0c;則表現為AC電源線兩端阻值低&#xff0c;呈短路狀態&#xff0c;否則可能是開關管擊穿。然后檢查直流輸出部分脫開負載&#…

java中整數如何表示,在Java中如何在位級別上內部表示整數?

慕瓜9086354Java整數為32位&#xff0c;并且總是帶符號的。這意味著&#xff0c;最高有效位(MSB)用作符號位。用an表示的整數int不過是位的加權和。權重分配如下&#xff1a;Bit# Weight31 -2^3130 2^3029 2^29... ...2 2^21 2^10 …

洛谷-P1160 隊列安排

題目 Problem Description 一個學校里老師要將班上N個同學排成一列&#xff0c;同學被編號為1&#xff5e;N&#xff0c;他采取如下的方法&#xff1a; 1.先將1號同學安排進隊列&#xff0c;這時隊列中只有他一個人&#xff1b; 2.2&#xff5e;N號同學依次入列&#xff0c;編號…

1.HTML小結

HTML 基本文檔 <!DOCTYPE html> <html> <head> <meta charset"UTF-8"> <title>文檔標題</title> </head> <body> 可見文本... </body> </html> <!DOCTYPE html>html文件聲明。charset"UTF-8…

方法參數名稱和Spring

繼續之前的博客文章有關構造函數和方法參數以及Java在運行時不保留參數名稱的情況–先前的文章涉及構造函數不保留參數名稱及其對Spring中的Contructor注入的含義&#xff0c;在此我將介紹更多內容不保留參數名稱的情況對Spring有影響&#xff1a; 1.考慮帶參數的Spring MVC C…

Fragment Or DialogFragment Can not perform this action after onSaveInstanceState

轉載&#xff1a;http://blog.csdn.net/chenshufei2/article/details/48747149 public void show(FragmentManager manager, String tag) {mDismissed false;mShownByMe true;FragmentTransaction ft manager.beginTransaction();ft.add(this, tag);ft.commit(); //注意這里…

php延遲更新,ThinkPHP開發指南-模型-高級模型之延遲更新

導航&#xff1a;上一頁我們經常需要給某些數據表添加一些需要經常更新的統計字段&#xff0c;例如用戶的積分、文件的下載次數等等&#xff0c;而當這些數據更新的頻率比較頻繁的時候&#xff0c;數據庫的壓力也隨之增大不少&#xff0c;我們可以利用高級模型的延遲更新功能緩…

three.js制作3d模型工具_3D打印模型打磨拋光常用工具

對于追求更好模型品質的人來說&#xff0c;對3D打印模型進行后處理工作是必不可少的&#xff0c;而后處理&#xff0c;首要的便是對模型進行打磨、拋光&#xff0c;將不屬于模型的耗材去除&#xff0c;提高表面光潔度。在此工作中&#xff0c;我們需要用到很多工具&#xff0c;…