浅谈Jmockit使用
2015-07-08 13:52
302 查看
最近公司里要求使用Jmockit来辅助单元测试。之前也没接触过,研究了几天,今天就跟大家谈谈我怎么使用Jmockit。写一个小例子供大家参考。
如有不对的地方还请大家多多指正
对于Mock的作用这里就不详细介绍了,不清楚的可以自行百度。笔者使用的是1.15版本的Jmockit(默认读者已经把相应的包导好)
在开始测试之前我们先写一个简单的Java类,代码如下
以上是一个极其简单的一个Java类,里面定义了一个getService方法。看了这个方法后可以确定,调用这个方法后得到的结果不是1就2.下面我们就来写一个小单元测试。
对于上面的单元测试我相信不会有人看不懂,而且简单运行一下就是一个长长的绿条。那下面我们就开始使用Mock来“修改”我们的GetServiceForBook类。
刚刚也说明了,对于getService方法的返回值不是1就是2。那如果我想让getService返回3怎么办?很简单,使用Mock。先上Expectations的方式。
现在,我们稍微修改下原来的GetServiceForBook类。
看到里面多了一个JustForTest的类,下面把JustForTest类代码贴出来
由于我们并没有mock掉getService所以返回值不是1就是2,对于上面的单元测试,给的参数是novel那返回值就应该是1。 然后我们运行一下可以发现控制台输出的是true而不是false了,这是因为我们把JustForTest类的getResult方法给Mock掉了。
里面还有两个注解一个@Tested一个是@Injectable。第一个@Tested不能变只能是这个,第二个可以写成@Mocked。如果第一个改成@Mocked的话输出结果就变成0,也就是说不过你的参数是什么结果都是输出0。这是因为在你使用Mocked注解时,如果没有进行“修改”,那系统就会自己帮你把这个类里的所有方法都Mock掉,而mock的内容就是返回默认值。(int的默认值是0)。
下面给出使用MockUp方式的
通过查阅Jmockit文档,发现MockUp有一个方法叫getMockInstance。也就是创建一个Mock实例。我们可以这样理解,每一个需要被Mock的代码都可以看作是一个对象。就拿上面getResult例子来说JustForTest可以把它看作是一个Mock对象。所以我们还可以改成下面的形式。
这次就先写到这里,其实对于Jmockit来说,这个只是沧海一栗,里面还有多东西需要研究,这里就先跟大家分享这么多,希望能对读者有用。
这是我第一次写博客,可能还有很多不足的地方,还请大大多多指教。
如有不对的地方还请大家多多指正
对于Mock的作用这里就不详细介绍了,不清楚的可以自行百度。笔者使用的是1.15版本的Jmockit(默认读者已经把相应的包导好)
在开始测试之前我们先写一个简单的Java类,代码如下
public class GetServiceForBook { public int getService(String bookType) { if ("novel".equals(bookType)){ return 1; } else { return 2; } } }
以上是一个极其简单的一个Java类,里面定义了一个getService方法。看了这个方法后可以确定,调用这个方法后得到的结果不是1就2.下面我们就来写一个小单元测试。
import static org.junit.Assert.*; import org.junit.Test; public class GetServiceForBookTest { private GetServiceForBook getServiceForBook = new GetServiceForBook(); @Test public void testBookService() { int test = getServiceForBook.getService("novel"); assertEquals(1,test); } }
对于上面的单元测试我相信不会有人看不懂,而且简单运行一下就是一个长长的绿条。那下面我们就开始使用Mock来“修改”我们的GetServiceForBook类。
刚刚也说明了,对于getService方法的返回值不是1就是2。那如果我想让getService返回3怎么办?很简单,使用Mock。先上Expectations的方式。
import static org.junit.Assert.*; import mockit.Expectations; import mockit.Injectable; import org.junit.Test; public class GetServiceForBookTest { @Injectable private GetServiceForBook getServiceForBook; @Test public void testBookService() { new Expectations(){ { getServiceForBook.getService(anyString); result = 3; times = 1; } }; int test = getServiceForBook.getService("novel"); assertEquals(3,test); } }以上就是使用Mock的方式把getService方法给“修改”了。所以底下的断言是看test和3的比较。很明显,这里用了Expectations把getService的返回值改成了3,也就是说在这个测试里不论我传进去的参数是什么,它的返回都是3.(使用@Injectable系统会自动注入,创建实例。)下面在给一个使用MockUp方式
import static org.junit.Assert.*; import mockit.Mock; import mockit.MockUp; import org.junit.Test; public class GetServiceForBookTest { private GetServiceForBook getServiceForBook = new GetServiceForBook(); @Test public void testBookService() { new MockUp<GetServiceForBook>(){ @Mock public int getService(String bookType) { return 3; } }; int test = getServiceForBook.getService("novel"); assertEquals(3,test); } }可以看出这两个Mock的结果是一样的都是把getService的方法改成3. 但是MockUp方式跟Expectations不同的是,MockUp把getService方法重新写了一遍并不像Expectations那样只要设定下变量就可以改变getService方法。
现在,我们稍微修改下原来的GetServiceForBook类。
package cn.com.liandisys.book.service; public class GetServiceForBook { JustForTest jft = new JustForTest(); public GetServiceForBook() { } public GetServiceForBook(JustForTest jft) { this.jft = jft; } public int getService(String bookType) { boolean flag = jft.getResult(); System.out.println(flag); if ("novel".equals(bookType)) { return 1; } else { return 2; } } }
看到里面多了一个JustForTest的类,下面把JustForTest类代码贴出来
public class JustForTest { public boolean getResult() { return false; } }依然是一个简单的Java类,我们可以看出这个JustForTest类里有一个getResult的方法,这个方法返回的永远是false. 在GetServiceForBook类里申明了一个JustForTest类并调用了getResult方法然后打印出来。不出意外这个输出结果应该永远都是false。那下面我们用Mock把getResult方法“修改”成true。
import static org.junit.Assert.*; import mockit.Expectations; import mockit.Injectable; import mockit.Tested; import org.junit.Test; public class GetServiceForBookTest { @Tested private GetServiceForBook getServiceForBook; @Injectable private JustForTest jft; @Test public void testBookService() { new Expectations(){ { jft.getResult(); result = true; times = 1; } }; int test = getServiceForBook.getService("novel"); assertEquals(1,test); } }
由于我们并没有mock掉getService所以返回值不是1就是2,对于上面的单元测试,给的参数是novel那返回值就应该是1。 然后我们运行一下可以发现控制台输出的是true而不是false了,这是因为我们把JustForTest类的getResult方法给Mock掉了。
里面还有两个注解一个@Tested一个是@Injectable。第一个@Tested不能变只能是这个,第二个可以写成@Mocked。如果第一个改成@Mocked的话输出结果就变成0,也就是说不过你的参数是什么结果都是输出0。这是因为在你使用Mocked注解时,如果没有进行“修改”,那系统就会自己帮你把这个类里的所有方法都Mock掉,而mock的内容就是返回默认值。(int的默认值是0)。
下面给出使用MockUp方式的
import static org.junit.Assert.*; import mockit.Mock; import mockit.MockUp; import org.junit.Test; public class GetServiceForBookTest { private GetServiceForBook getServiceForBook = new GetServiceForBook(); @Test public void testBookService() { new MockUp<JustForTest>(){ @Mock public boolean getResult() { return true; } }; int test = getServiceForBook.getService("novel"); assertEquals(1,test); } }这里就不多解释了,跟上面的MockUp例子很像,同样也是把getResult输出true。
通过查阅Jmockit文档,发现MockUp有一个方法叫getMockInstance。也就是创建一个Mock实例。我们可以这样理解,每一个需要被Mock的代码都可以看作是一个对象。就拿上面getResult例子来说JustForTest可以把它看作是一个Mock对象。所以我们还可以改成下面的形式。
import static org.junit.Assert.*; import mockit.Mock; import mockit.MockUp; import org.junit.Test; public class GetServiceForBookTest { private GetServiceForBook getServiceForBook; @Test public void testBookService() { JustForTest mock = new MockUp<JustForTest>(){ @Mock public boolean getResult() { return true; } }.getMockInstance(); getServiceForBook = new GetServiceForBook(mock); int test = getServiceForBook.getService("novel"); assertEquals(1,test); } }这就是为什么我去重写getServiceForBook的构造函数,把Mock创建出来的对象赋给getServiceForBook里的JustForTest,这样也能达到Mock的目的
这次就先写到这里,其实对于Jmockit来说,这个只是沧海一栗,里面还有多东西需要研究,这里就先跟大家分享这么多,希望能对读者有用。
这是我第一次写博客,可能还有很多不足的地方,还请大大多多指教。
相关文章推荐
- [Win32SDK基本] 模态窗口 和 多窗口
- 每天一个linux命令(20):find命令之exec
- 练手之作-公司点饭系统
- 深入Java集合学习系列:HashMap的实现原理
- SQL_ROW_NUMBER 用于分页存储
- How to write conditional equations
- ibatis.net中Iterate的使用
- 年轻人你活着不是为了看K线!
- Hibernate与JDBC事务整合
- poj1258 Agri-Net 最小生成树
- 系统管理:查看cpu、内存、磁盘、I/O、负载、性能状态
- 每天一个linux命令(19):find 命令概览
- Freemarker输出$和html标签等特殊符号
- IPA 包不经过APP Store直接发布到网站供用户下载安装
- 大数据架构及流处理架构
- xcode模拟器的安装路径
- 膝盖中了一箭之手术篇
- 编写Windows Service 备忘
- AndroidAnnotations快速开发框架
- Serializable:自定义序列化