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));
Friend());
}
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");
Name());
}
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", Name());
}};
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);
}
结果为
equals()方法java.lang.IllegalArgumentException: Invalid null value passed as argument 0
at jmockito.PersonServiceTest$4.<init>(PersonServiceTest.java:92)
at stShowFriendUseAny(PersonServiceTest.java:91)
flect.NativeMethodAccessorImpl.invoke0(Native Method)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
at cution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
at cution.junit.JUnitStarter.main(JUnitStarter.java:68)
at cution.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", Friend());
}};
personService.showFriendInfo(person);
}
结果为
show friend info ...
show info1 ...
到这⾥,似乎可以得出这样⼀个结论,mock内部调⽤⽅法时,其mock参数与外部参数的关系,应该与实际执⾏时,参数的关系⼀致。即实际调⽤中,showInfo2的参数是Friend(),
所以,在mock⽅法showInfo2时,其参数也应该是Friend()。
如果是这样的话,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等。
当然,像这⼀类的问题,如果要了解清楚,最好还是去阅读源代码。暂时没有时间做这件事。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论