使用 mockito 在抽象超级 class 中设置私有字段

Setting private field in abstract super class using mockito

我有一个抽象的超级 class TP 和一个具体的子 class ETP。这是我的代码:

    abstract class TP {

    private Configuration app;        
         protected MC bMC() {    
         }
    }

和子class ETP代码是:

 public class ETP extends TP {        
    private Configuration app;       
       public MC pT() {
          bMC();
       }
   }

我正在为 ETP 编写测试用例,它是 ETPTest,看起来像这样

public class ETPTest {       
 @Before
    public void setUp() throws Exception {
       // as TP is abstract i am initializing with ETP
          TP = new ETP();        
       // some initialization
   }    
    Whitebox.setInternalState(TP, app);
}

但应用程序在 TP 中作为 null 传递并在 TP 中获取 NPE。

有什么想法或建议吗?

app是TP和ETP中都定义的私有变量;我正在尝试为 TP 中的应用程序设置内部状态。

你对这些事情的困难可以看作是一种症状。

您可以决定解决方法是花费数小时,直到您获得 mocking 部件来规避该问题。

而另一个选项是:理解给定的设计有缺陷:

  • sub classes 应该绝对 not 关心 super classes 中的 private 字段。 private 的全部意义在于让其他 class 不应该知道或关心的 "implementation detail" 事情
  • 更糟:通过设置一个同名的 second 私有字段,您只会增加混乱。那些将是不同的私人领域;这里没有 "overriding" 或 "polymorphism"。

最后,您可能不明白如何正确设计一个使用继承和抽象基classes的解决方案。因此,您应该退一步思考,例如,如果这样的解决方案有帮助:

public abstract class Base {
  protected abstract Configuration getConfiguration();

  public final void doSomething() {
    ... calls getConfiguration() to do its jobs
  }
}

然后:

public abstract class Subclass extends Base {
  protected Configuration getConfiguration() {
    return whatever

作为一条经验法则:干净、直截了当、不令人惊讶的设计通常可以简单地通过使用依赖注入和这里一个 mock 和另一个 mock 来进行单元测试。一旦你必须研究所有这些复杂的 "solutions";比如mocking super-classmethods/fields;或模拟静态方法,......你已经遭受了糟糕的设计;而不是解决那个问题;您尝试解决它。

这对你的长期帮助不大 运行。因为真正的问题是生产代码中的 "smelly" 设计。