jmockito模拟方法中参数如何指定
在做单元测试的时候,经常会遇到mock类的方法的情景。在写单测过程中,遇到一些问题,比较困惑,便做了一些测试,并得出一个结论:
在mock类的方法时,当符合 (mock参数).equals(实际调用过程中的参数)时,才可以mock成功;当参数为基本类型时,可以使用angLong等。
下面是测试的欢乐时间啦:
首先看测试基础类:
public class Person {
private String name;
private Integer age;
private Person friend;
}
public class PersonService {
public void showFriendInfo(Person person){
System.out.println("show friend info ...");
showInfo1(new Person("shoren", 22));
showInfo2(person.getFriend());
}
public void showInfo1(Person person){
System.out.println("show info1 ...");
}
public void showInfo2(Person person){
System.out.println("show info2 ...");
}
public void showPersonInfo(Person person){
System.out.println("show person info ...");
showName("shoren");
showName2(person.getName());
}
public void showName(String name){
System.out.println("show name1 : " + name);
}
public void showName2(String name){
System.out.println("show name2 : " + name);
}
}
先看参数为基本类型时:
1. 参数为基本类型时,使用any都可以成功mock。
@Test
public void testShowPersonInfoUsingAny(){
final Person person = new Person("manyao", 23);
new NonStrictExpectations(personService){{
Deencapsulation.invoke(personService, "showName", anyString);
Deencapsulation.invoke(personService, "showName2", anyString);
}};
personService.showPersonInfo(person);
}
结果为
show person info ...
2. 参数为基本类型,mock时传入真实的值,且与之前值相等,可以mock成功。
@Test
public void testShowPersonInfoUsingData(){
final Person person = new Person("manyao", 23);
new NonStrictExpectations(personService){{
Deencapsulation.invoke(personService, "showName", new String("shoren"));
Deencapsulation.invoke(personService, "showName2", new String("manyao"));
}};
personService.showPersonInfo(person);
}
结果为:
show person info ...
3. 参数为基本类型,mock时传入真实的值,若实际调用值与之不相等,则mock失败。
@Test
public void testShowPersonInfoUsingData2(){
final Person person = new Person("manyao", 23);
new NonStrictExpectations(personService){{
Deencapsulation.invoke(personService, "showName", new String("tata"));
Deencapsulation.invoke(personService, "showName2", person.getName());
}};
personService.showPersonInfo(person);
}
结果为
show person info ...
show name1 : shoren
得出结论:如果参数为基本类型,则mock参数为anyXXX 或者 与实际调用的参数值相等时,可以mkco成功。
再来看参数为复杂类型:
4. 参数为复杂参数时,使用any做类型转换,mock失败。
@Test
public void testShowFriendUseAny(){
final Person person = new Person("manyao", 23);
person.setFriend(new Person("friend", 24));
new NonStrictExpectations(personService){{
Deencapsulation.invoke(personService, "showInfo1", (Person)any);
Deencapsulation.invoke(personService, "showInfo2", (Person)any);
}};
personService.showFriendInfo(person);
}
结果为
java.lang.IllegalArgumentException: Invalid null value passed as argument 0
at jmockito.PersonServiceTest$4.<init>(PersonServiceTest.java:92)
at jmockito.PersonServiceTest.testShowFriendUseAny(PersonServiceTest.java:91)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
5. 参数为复杂参数,mock参数为具体值时,mock参数 equals 实际调用值时,mock成功。
@Test
public void testShowFriendUseData(){
final Person person = new Person("manyao", 23);
person.setFriend(new Person("friend", 24));
new NonStrictExpectations(personService){{
Deencapsulation.invoke(personService, "showInfo1", new Person("shoren", 22));
Deencapsulation.invoke(personService, "showInfo2", person.getFriend());
}};
personService.showFriendInfo(person);
}
结果为
show friend info ...
show info1 ...
到这里,似乎可以得出这样一个结论,mock内部调用方法时,其mock参数与外部参数的关系,应该与实际执行时,参数的关系一致。即实际调用中,showInfo2的参数是person.getFriend(),
所以,在mock方法showInfo2时,其参数也应该是person.getFriend()。
如果是这样的话,mock方法showInfo1时,又该如何呢?在Person中添加equals方法测试一下。
6. 参数为复杂参数时,(mock参数).equals(实际参数)时,mock成功。
@Test
public void testShowFriendUseData1(){
final Person person = new Person("manyao", 23);
person.setFriend(new Person("friend", 24));
new NonStrictExpectations(personService){{
Deencapsulation.invoke(personService, "showInfo1", new Person("shoren", 22));
Deencapsulation.invoke(personService, "showInfo2", new Person("friend", 24));
}};
personService.showFriendInfo(person);
}
结果为
show friend info ...
7. 参数为复杂参数时,修改equals方法,总是return true时。不论mock参数如何,mock成功.
@Test
public void testShowFriendUseData2(){
final Person person = new Person("manyao", 23);
person.setFriend(new Person("friend", 24));
new NonStrictExpectations(personService){{
Deencapsulation.invoke(personService, "showInfo1", new Person());
Deencapsulation.invoke(personService, "showInfo2", new Person());
}};
personService.showFriendInfo(person);
}
结果为
show friend info ...
综上,我们得出结论:
在mock类的方法时,当符合 (mock参数).equals(实际调用过程中的参数)时,才可以mock成功;当参数为基本类型时,可以使用angLong等。
当然,像这一类的问题,如果要了解清楚,最好还是去阅读源代码。暂时没有时间做这件事。
jmockito模拟方法中参数如何指定的更多相关文章
- C#方法中参数ref和out的解析
一.C#方法中参数类型 有4种参数类型,有时候很难记住它们的不同特征,下图对它们做一个总结,使之更容易比较和对照. 二.C#方法中的参数 1.值参数 使用值参数,通过复制实参的值到形参的方式把数据传递 ...
- 详解SpringMVC中Controller的方法中参数的工作原理[附带源码分析]
目录 前言 现象 源码分析 HandlerMethodArgumentResolver与HandlerMethodReturnValueHandler接口介绍 HandlerMethodArgumen ...
- 详解SpringMVC中Controller的方法中参数的工作原理
Spring MVC中Controller的处理方法的参数可以是Integer,String,自定义对象,ServletRequest,ServletResponse,ModelAndView等等,非 ...
- 详解SpringMVC中Controller的方法中参数的工作原理——基于maven
转自:http://www.tuicool.com/articles/F7byQn 前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不熟悉,那么请参考它的入门blog:ht ...
- 【MVC - 参数原理】详解SpringMVC中Controller的方法中参数的工作原理[附带源码分析]
前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不熟悉,那么请参考它的入门blog:http://www.cnblogs.com/fangjian0423/p/spring ...
- 动作方法中 参数,Json
一.方法中可以出现的参数类 1.HttpServletRequest 2.HttpServletResponse 3.HttpSession 4.Model 二.返回接收json数据 1. 接收,返回 ...
- main方法中参数"String[ ] args"详解
1.在编写完一个有主方法的java文件时,需要在cmd窗口中先编译此java文件(javac xxx.java),然后再运行(java xxx) 其实在运行java xxx的时候如果后面跟着参数用空格 ...
- JAVA方法中参数到底是值传递还是引用传递
当一个对象被当作参数传递到一个方法后,在此方法内可以改变这个对象的属性,那么这里到底是值传递还是引用传递? 答:是值传递.Java 语言的参数传递只有值传递.当一个实例对象作为参数被传递到方法中时,参 ...
- 将前端请求中的数据绑定到Spring MVC响应方法中参数的四种方法
一.映射URL绑定的占位符到方法参数 1.方法 使用@PathVariable注解 2.代码示例 a.接收请求方法 @RequestMapping(value = "/deleteInfo/ ...
随机推荐
- 4.3 lambda表达式
函数,封装的代码块可以很复杂,也可以很简单.当函数的代码块简单到只有一个表达式,就可以考虑用lambda表达式,也称匿名函数. 1 lambda表达式基础 #首先需要声明一点:lambda是表达式而非 ...
- 求指定区间内与n互素的数的个数 容斥原理
题意:给定整数n和r,求区间[1, r]中与n互素的数的个数. 详细见容斥定理 详细代码如下 int solve(int r, int n) { vector<int>p; p.clear ...
- uva11400 动态规划
没种电压灯泡要么全换,要么不换.状态d(i)表示前i种灯泡的最低价格. 转移方程: dp[i]=min(dp[i],dp[j]+(s[i]-s[j])*d[i].c+d[i].k); AC代码: #i ...
- nyoj913 取石子(十) SG函数 + Nimm博弈
思路: 第一堆:SG = n % 3; 第二堆:无规律,打表即可,用hash比set快很多; 第三堆:SG = n; 第四堆:无规律 第五堆:SG = n % 2; 第六堆:SG = n % (i + ...
- struts2标签库----数据标签详解
上篇文章我们介绍struts2标签库中的控制标签的基本使用和部分原理,本篇文章接着了解下标签库中有关数据标签的使用和原理.主要涉及以下数据标签: action标签:用于在视图页面跳转到一个Action ...
- iOS学习 NSString常用技巧
字符串是程序设计最常用的数据类型之一了.在Mac/iPhone编程中,苹果为我们提供了一个不同的字符串类型NSString.有别与普通的String为数据类型,NSString其实是一个对象类型.NS ...
- [JCIP笔记] (一)多线程的起源
在很久很久以前,那时的计算机还没有操作系统这种东西,所以只能有一个程序,从头到尾地跑.于是这个程序要负责使用所有的资源,还得响应外部请求.想想这个程序得多复杂啊--为了做成一件事,可能要先把内存啊.I ...
- GOF23种设计模式精解
创建型 1. Factory Method(工厂方法) 2. Abstract Factory(抽象工厂) 3. Builder(建造者) 4. Prototype(原型) 5. Singleton( ...
- Java的Random总结
/** * @Title:RandomNum.java * @Package:com.yhd.chart.model * @Description:Java产生随机数 * @author:Youhai ...
- 用DirectShow实现视频采集-流程构建
DirectShow作为DirectX的一个子集,它为用户提供了强大.方便的多媒体开接口,并且它拥有直接操作硬件的能力,这使得它的效率远胜于用GDI等图形方式编写的多媒体程序.前面一篇文章已经对Dir ...