如何在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'sspy机制:

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中模拟单个方法的主要内容,如果未能解决你的问题,请参考以下文章

带有软删除的 Spring Boot GET 方法如何在服务 impl 中添加另一个异常

RDD take()方法如何在内部工作?

表单的 post 方法如何在幕后实际工作

如何用 jest 解开单个实例方法

Jquery中each方法如何在其所调用函数中退出遍历

适用于Android的Visual Studio模拟器:如何更改键盘语言