大概兩周前,接了個補寫Unit Test
的任務备绽,此事在難度在于service
代碼不是我寫的驮配,而且它是調(diào)用ElasticSearch API
的。
作為一個Java UT
小白同诫, 在經(jīng)過一番緊急惡補之后粤策,便操刀上手了,用上了常規(guī)的Mockito
误窖,然后得到卻是更為經(jīng)典的NullPointException
叮盘。
在嘗試各種花樣之后,還是一無所獲霹俺,此間操作總結(jié)起來就是:一頓操作猛如虎柔吼,定睛一眼原地杵!
終于一番谷歌本文的標題之后丙唧,我在ElasticSearch
的官網(wǎng)討論區(qū)和Github Issues
中得到了它們:
- (1) https://discuss.elastic.co/t/resthighlevelclient-mocking/123027
- (2) RestHighLevelClient impossible mocking
- (3) Unable to effectively create decorator class for RestHighLevelClient due to final modifiers
通讀之后得到三點信息:
- 討論(2)中說到愈魏,
ElasticSearch
的某次更新中將所有的modifiers
都更改為final
,而眾所周知的是Mokicto
并不支持final
和static
想际,所有mock
的結(jié)果就是得到灰常經(jīng)典的NullPointException
培漏。盡管ElasticSearch
的維護者知曉這一狀況,并有部分理解這種需求胡本,但他們的決定是仍然維持當前狀況北苟,不會對Mockito.mock()
妥協(xié)。 - 整個(1)中的討論打瘪、(2)中的一兩個回復和(3)的前半部分,都提到了一種解決方法傻昙,就是寫實現(xiàn)
service
調(diào)用ElasticSearch API
的時候闺骚,自行加一層封裝纵苛,這樣在使用Mockito.mock()
的時候只需要針對封裝后的接口進行猪瞬。這種方案對當時的我不太適用,因為這涉及到項目的重構(gòu)工作呛哟。 - (3)的后半部分代碼示例中給出了另一個解決方案——
PowerMockito
贾惦,這也是我最終完成工作的方案胸梆,它支持final
和static
的mock
操作,它在Mockito
的基礎(chǔ)上做了更多工作须板,可以視為Mockito 2.0
碰镜。只不過代碼示例的實現(xiàn)我是沒能跑起來的,具體使用可以看對應的官方文檔习瑰,我也寫了一篇比較潦草的PowerMockito實戰(zhàn)及心得
記錄了一兩個趟過的坑绪颖。