如何在java中模拟单个方法
Posted
技术标签:
【中文标题】如何在java中模拟单个方法【英文标题】:How to mock a single method in java 【发布时间】:2012-06-09 08:53:13 【问题描述】:是否可以模拟 Java 类的单个方法?
例如:
class A
long method1();
String method2();
int method3();
// in some other class
class B
void someMethod(A a)
// how would I mock A.method1(...) such that a.method1() returns a value of my
// choosing;
// whilst leaving a.method2() and a.method3() untouched.
【问题讨论】:
【参考方案1】:使用Mockito's
spy机制:
A a = new A();
A aSpy = Mockito.spy(a);
Mockito.when(aSpy.method1()).thenReturn(5l);
对于任何未存根的方法,使用 spy 调用包装对象的默认行为。
Mockito.spy()/@Spy
【讨论】:
或者,如文档所述,in some cases 你需要Mockito.doReturn(51).when(aSpy).method1();
。
不幸的是,您不能以这种方式监视 final 类的实例。 :(
一般来说,不可能模拟任何最终的东西。 final 类中的方法也被视为 final。
@JohnB 我们如何使用Mokito spy
模拟私有方法?
试试 PowerMockito:***.com/questions/7803944/…【参考方案2】:
使用spy()
method from Mockito,并像这样模拟您的方法:
import static org.mockito.Mockito.*;
...
A a = spy(new A());
when(a.method1()).thenReturn(10L);
【讨论】:
【参考方案3】:根据 Mockito 的文档,公认的答案不是窥探真实对象的正确方法。
正确的做法是使用以下模式:doReturn("foo").when(spy).get(0);
您可以在下面找到来自 Mockito 的关于 Spying on real objects 的 sn-p。
监视真实物体的重要问题! 有时这是不可能的或 使用 when(Object) 来存根间谍是不切实际的。因此当 使用间谍请考虑 doReturn|Answer|Throw() 系列方法 用于存根。示例:
List list = new LinkedList(); List spy = spy(list); //Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty) when(spy.get(0)).thenReturn("foo"); //You have to use doReturn() for stubbing doReturn("foo").when(spy).get(0);
Mockito 不委托调用 到传递的真实实例,相反它实际上创建了它的副本。 因此,如果您保留真实实例并与之交互,请不要指望 间谍要意识到这些互动及其对现实的影响 实例状态。推论是当一个 unstubbed 方法是 在间谍上调用但不在真实实例上,你不会看到任何 对真实实例的影响。注意最终方法。莫基托 不模拟最终方法,所以底线是:当你监视真实的 对象+您尝试存根最终方法=麻烦。你也不会 也能够验证这些方法。
【讨论】:
【参考方案4】:假设您使用的是 jmockit:
public void testCase(@Mocked("methodToBeMocked") final ClassBoBeMocked mockedInstance)
new Expectations()
mockedInstance.methodToBeMocked(someParameter); returns(whateverYouLikeItToReturn);
mockedInstance.callSomemethod();
【讨论】:
【参考方案5】:您可以简单地创建一个覆盖method1()
的A
的子类。
【讨论】:
这行不通-因为您必须将 A 的现有实例传递给 A 的子类,以便子类返回 a.method2() 和 a.method3()分别调用 method2() 和 method3()。这意味着子类将覆盖 method2() 和 method3()。 @user63904: 啊,所以你想修改方法 1 INSIDE someMethod() 的行为,同时仍然使用作为参数传递的 A 的实例?对,那不行。以上是关于如何在java中模拟单个方法的主要内容,如果未能解决你的问题,请参考以下文章