大概两周前,接了个补写Unit Test
的任务,此事在难度在于service
代码不是我写的,而且它是调用ElasticSearch API
的。
作为一个Java UT
小白, 在经过一番紧急恶补之后,便操刀上手了,用上了常规的Mockito
,然后得到却是更为经典的NullPointException
。
在尝试各种花样之后,还是一无所获,此间操作总结起来就是:一顿操作猛如虎,定睛一眼原地杵!
终于一番谷歌本文的标题之后,我在ElasticSearch
的官网讨论区和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
的结果就是得到灰常经典的NullPointException
。尽管ElasticSearch
的维护者知晓这一状况,并有部分理解这种需求,但他们的决定是仍然维持当前状况,不会对Mockito.mock()
妥协。 - 整个(1)中的讨论、(2)中的一两个回复和(3)的前半部分,都提到了一种解决方法,就是写实现
service
调用ElasticSearch API
的时候,自行加一层封装,这样在使用Mockito.mock()
的时候只需要针对封装后的接口进行。这种方案对当时的我不太适用,因为这涉及到项目的重构工作。 - (3)的后半部分代码示例中给出了另一个解决方案——
PowerMockito
,这也是我最终完成工作的方案,它支持final
和static
的mock
操作,它在Mockito
的基础上做了更多工作,可以视为Mockito 2.0
。只不过代码示例的实现我是没能跑起来的,具体使用可以看对应的官方文档,我也写了一篇比较潦草的PowerMockito实战及心得
记录了一两个趟过的坑。
网友评论