您现在的位置是:首页 > 文章详情

单元测试时静态方法注意点

日期:2018-11-13点击:450

Mockito 很强大, 但是它不支持静态方法.所以, 就用Powermock了. 要测试的对象是Controller中的接口, 对单元测试来说, 这个待测试的街口应该是一个白盒的. 所以, 其中的第三方(service,其他静态类)的调用都应该使用mock对象来stub起来. 下面是## 示例代码(随手写的,说明问题就行):

Controller:  

@Controller public class MainController {     @Autowired     private MainService mainService;     @GetMapping("/hello")     public String hello(){         mainService.hello();         String result = HelloUtil.hi();         if(result.equals("hi")){             return "ok";         }else {             return "fail";         }     } } 

Service:

/**  * Created by icer on 2017/10/13.  */ @Service public class MainService {     public String hello(){         System.out.println("hello");         return "hello";     } } Util静态类: ```java public class HelloUtil {     public static String hi(){         return "hi";     } } 

我们要测试的是MainController中的hello方法.

再次注意, 是hello方法,不是hello接口.  我们的测试类:

@RunWith(PowerMockRunner.class) @PrepareForTest(HelloUtil.class) public class MainControllerTest {     [@Mock](https://my.oschina.net/mock)     private MainService mainService;     @InjectMocks     private MainController mainController;     [@Test](https://my.oschina.net/azibug)     public void helloTest(){         PowerMockito.when(mainService.hello()).thenReturn("hello");         PowerMockito.mockStatic(HelloUtil.class);         PowerMockito.when(HelloUtil.hi()).thenReturn("hi");         HelloUtil.hi();         HelloUtil.hi();         String result = mainController.hello();         PowerMockito.verifyStatic(Mockito.times(3));         HelloUtil.hi();         HelloUtil.hi();         HelloUtil.hi();      // mainController.hello();         assertEquals(result, "ok");     } } 

我们着重看的是上面的HelloUtil.hi()方法.

PowerMockito.verifyStatic(Mockito.times(3)); 

先说下这句的意思, 这句(后面简称静态校验)就是对静态方法的调用次数做了校验. 光看命名就能想通. 但是要注意的是, 这里的3指的是在静态校验之前的调用次数. 如果静态校验执行的次数不等于这个次数, 那么静态校验后面的静态方法就不能再执行了. 上面代码中, 在这句前一共执行了三次HelloUtil.hi(); 两次是主动明文执行的, 一次是在mainController.hello()里面执行的. 如果注释掉某一个, 那么就会看到日志打印:

org.mockito.exceptions.verification.TooLittleActualInvocations:  cn.com.hanbinit.utils.HelloUtil.hi(); Wanted 3 times but was 2 times. 

这里只校验静态校验之前的执行次数, 后面执行多少次都没关系. 另外, 还有一点要注意的是, 在校验语句前, 我们前面给方法mock的返回值是有效的, 在校验之后就没效果了. 
所以, 我们对静态方法的测试, 应该是放在verifyStatis之前进行的.  在校验之后的执行, 是为了证明我们之前的校验是ok的.

校验之后的静态方法调用, 是一定要有的. 要不然是测试不出调用次数的. 参见下面代码:

@Test     public void helloTest(){         PowerMockito.when(mainService.hello()).thenReturn("hello");         PowerMockito.mockStatic(HelloUtil.class);         PowerMockito.when(HelloUtil.hi()).thenReturn("hi");         String result = HelloUtil.hi();         String hi = HelloUtil.hi();         PowerMockito.verifyStatic(Mockito.times(4));         assertEquals(result, "hi");     } 

像上面这段代码, 测试是通过的.  改成下面这样:

@Test     public void helloTest(){         PowerMockito.when(mainService.hello()).thenReturn("hello");         PowerMockito.mockStatic(HelloUtil.class);         PowerMockito.when(HelloUtil.hi()).thenReturn("hi");         String result = HelloUtil.hi();         String hi = HelloUtil.hi();         PowerMockito.verifyStatic(Mockito.times(4));         HelloUtil.hi();         assertEquals(result, "hi");     } 

就能看到日志:

org.mockito.exceptions.verification.TooLittleActualInvocations:  cn.com.hanbinit.utils.HelloUtil.hi(); Wanted 4 times but was 2 times. 

所以, 对静态方法调用次数的校验一定是verifyStatis和之后的显示调用一起来进行的. 最后的最后, 再提一句:  如果同时有多个静态方法调用. 如果都要验证调用次数, 那么应该分别像下面这样使用多次:

PowerMockito.verifyStatic(Mockito.times(4)); HelloUtil.hi(); 

  [1]: https://blog.hanbinit.com.cn/usr/uploads/2017/10/12449159.png

原文链接:https://my.oschina.net/hanbin/blog/2875842
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章