先決條件:我使用的是最新版本的Play! framework和Java版本(不是Scala)。測試與外部服務的交互
我需要在創建用戶時向消息隊列發佈消息,並且我想測試該行爲。我的問題是使這個易於測試。
的控制方法
在其他框架,我就做了是使用構造器注入到控制器,並通過在我的測試中嘲笑隊列;但是,與Play!控制器是靜態的,這意味着我不能在我的測試中做new MyController(mockedQueue)
。
我可以使用Google Guice並將一個@Inject
註釋放在控制器的靜態字段中,但對我來說這並不好,因爲這意味着我必須將該字段公開爲在測試中被替換,或者我必須在測試中使用容器。我更喜歡使用構造函數注入,但玩!似乎並沒有促進這一點。
模型方法
人們常常說你的邏輯應該是在你的模型,而不是你的控制器。這就說得通了;然而,我們不在Ruby這裏,讓你的實體與外部服務(電子郵件,消息隊列等等)交互...比在動態環境中可測試性要差得多,在這種環境中,你可以用一個模擬實例替換你的靜態調用將。
如果我讓實體呼叫進入隊列,那麼可測試性如何?
當然,如果我進行端到端的集成測試,這兩種情況都是不必要的,但我寧願不需要消息隊列或SMTP服務器啓動我的測試運行。
所以我的問題是:我該如何建模我的Play!控制器和/或模型來促進測試與外部服務的交互?
「ServiceFactory」方法存在的一個*潛在問題是該字段將被初始化;因爲它是一個靜態字段,所以'getInstance'可能會在您有機會替換實例之前被初始化程序調用。只是大聲思考,沒有實際驗證這一點。 –
實際上,在這個例子中,ServiceFactory是一個Singleton。您不會替換ServiceFactory本身,而是替換它生成的QueueService。 –
是的,我明白了;但是,由於該字段是靜態的,因此在您能夠替換從getInstance返回的任何值之前,它將被初始化。您通常無法控制執行靜態初始化程序的時間,因此可能會在測試設置發生之前發生。 –