最近由于项目的需要,开发后的代码强制编写Junit测试,并且达到一定的coverage probility(主要应付客户).所以,为了达到一定的覆盖率,鄙人不得不在Case中大量使用反射(一般是针对private方法)和JMock(主要针对一些属性方法)。
小编是做开发出身,由于对Spring的源代码有过或多或少的了解,因此对反射技术也有一定的了解。故在使用反射进行Junit测试的过程中,还算是没有遇到太多问题。小编认为,使用反射最重要的是要分清两点: 一是要反射的实现类(记住,这里的对象类型必须是具体的实现类,而非接口);二就是要通过反射调用的方法(一般这里指的是private方法),这里需要注意方法重构的情况;对于鄙人来说,最头疼的就剩下JMock方式了。
其实说来惭愧,小编接触JMock还是在今年11月份,当时被发配到一个做纯后台的项目;当时就想JMock只是针对Junit测试的技术,对于我们开发人员来说没有什么太大的关系,不用过多的了解。感觉哥们不用JMock一样可以把Junit做好,一样可以把覆盖率提高;随着单元测试进行,我慢慢发现:有些方法如果不使用JMock花费的时间和精力要远远比使用JMock多的多,由于项目赶时间,公司没有过多的时间让我们花费在Junit test上,所以,鄙人感觉还是应该重申一下自己的立场,感觉还是应该对JMock了解一下,不光是加快现在的Junit测试的进度,还应该补充一下自己在Junit测试上的知识;
(注: 以下内容都是笔者自己的理解,如果有哪些地方不妥当的,还望各位大侠给出建议,小编在此先谢谢啦!!!!)
1. 首先就是创建MockContext,用来构造具体要被mock的方法对象。
2. 通过step1创建的mockContext构造具体的mock对象。
eg:mockContext.mock(Class,ObjectAgentName);
其中mock方法中的参数,Class指的是要构造的mock对象的类型,这里只能是接口;ObjectAgentName指的是被mock对象的代理名称,这个参数不是必须的;如果没有这个参数,当前就会根据Class创建默认的代理名称;
注意: 在MockContext中,代理名称唯一,也就是不能出现名称相同的两个mock对象。
3. 通过mockContext.checking()方法把mock对象替代具体代码中的对象。
eg:
mockContext.checking(new Expectations() {
{
// 1. 具体参数,当参数为"dandan"的时候,addressServcie对象的findAddresses方法用returnIterator返回一个Iterator<Address>对象。
allowing(addressServcie).findAddresses("dandan");
will(returnIterator(addresses));
// 2. 参数类型,当参数为String类型的时候,addressServcie对象的findAddresses方法用returnIterator返回一个Iterator<Address>对象。
allowing(addressServcie).findAddresses(noNull(any(String.class)));
will(returnIterator(addresses));
// 当参数为"dandan"的时候,addressServcie对象的findAddresses方法用returnIterator返回一个Iterator<Address>对象。
oneof(addressServcie).findAddresses("dandan");
will(returnIterator(addresses));
// 在代码中多次执行被mock的方法对象的时候。
atList(1).of(addressServcie).findAddresses(noNull(any(String.class)));
will(returnIterator(addresses));
}
});