繁体   English   中英

如何模拟带有私有字段的课程?

[英]How do I mock a class with private fields?

我正在尝试使用Mockito测试单例类,如下所示:

  public class Single {
     private ID id;
     private Single(){}  //private constructor 
     public static Single getSingle(){ // ***code to get instance*** }

     // method I want to test
     public String getName(){ 
        String name = id.getRawName(); // need field id here
        ** additional operations on name ** // code need to be tested
        return name;
     }

  }

我尝试模拟此类,并使用反射设置字段“ id”,如下所示:

Single sg = Mockito.mock(Sincle.class);
Field myID = sg.getClass().getDeclaredField("id"); // fails here
myID.setAccessible(true);
myID.set(sg, <ID instance>);

但是,它在getDeclaredField()方法中失败,例外

java.lang.NoSuchFieldException:id

我猜这是因为实例sg中的id字段为null

所以我想知道是否可以在不修改原始类的情况下测试此方法?

模拟不是真实的对象。 您不能设置模拟的声明字段,因为它不存在1

在编写测试时,通常希望模拟所有不是的类:

  • 被测系统 (在本例中为Single )类
  • 数据结构(如List )和其他POJO

因此,您真正要嘲笑的东西是ExternalCall ,您并没有真正解释它在您的问题中的工作方式。 但是,如果这是静态方法,则需要使用PowerMock 请参阅: 用Mockito模拟静态方法

请注意,您的错误是NoSuchFieldException ,因为您实际上没有真实的实例。 不是因为:

我猜这是因为实例sg中的id字段为null

这是因为该字段在模仿生成的子类中 实际上不存在1 ,不是因为它为null

1:它确实存在于模拟的超类(在本例中为Single )中,但是其值被模拟行为捕获,除非您将其用作部分模拟,否则它将被忽略。 但是,这是技术细节,与Mockito的正确使用无关。

...在不修改原始类的情况下,我能做些什么来测试此方法?

就在这里。 将Mockito用作面包和黄油:

when(sg.getId()).thenReturn("123")

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM