如何模拟在依赖类中初始化的私有最终客户端的方法?

问题描述 投票:0回答:1

我有一个看起来像这样的类:

class A {
    private final B b;

    public A(String x, String y){
        b = new B(x,y);
    }


    public void someMethod() {
        b.externalMethod();
    }
}

现在我在 drools 规则中实例化 A 并调用

someMethod()
但我想避免调用
externalMethod()
。有没有办法做到这一点?

我试过使用

mockedConstruction
B
但我面临 2 个问题:

  1. Mockito 只允许每个线程 1 个静态模拟,所以如果我在一个规则中有多个客户端(类型 A),那将是不可行的。
  2. 我无法使用它断言异常,因为
    mockedConstruction
    使用lambda函数并做类似
    doThrow(someException).when(b).externalMethod()
    的事情会在模拟创建本身而不是方法调用上给出异常。

任何帮助表示赞赏。如果语言不清楚或我遗漏了任何细节,我深表歉意(请提及)。

java mockito junit5 powermock powermockito
1个回答
0
投票

首先,我会尝试在没有模拟的情况下进行(如果可能的话)。例如,

someException
何时被 b.externalMethod() 抛出? 也许您可以通过
x
y
参数或一些测试配置导致这种情况发生:这将允许您进行无模拟测试。 :)


如果这不可能,我会开始研究这个类的设计,这使得它很难测试。您可以做的最简单的事情是使用依赖注入并添加 A 的构造函数,该构造函数接收 B 的实例作为参数:

class A {
    private final B b;

    public A(String x, String y){
        this(new B(x,y));
    }
        
    public A(B b){
        this.b = b;
    }
    // ...
}

这样,在测试中,您将能够轻松地注入模拟:

B mockedB = Mockito.mock(B.class); A testedA = new A(mockedB);

when(mockedB.externalMethod()).thenThrow(someException);

如果您不喜欢另一个公共构造函数的想法,您至少可以考虑一个受包保护的构造函数。但总的来说,我认为第二个公共构造函数是可行的方法,如果您使用的是 Lombok,则可以使用

@RequiredArgConstructor

© www.soinside.com 2019 - 2024. All rights reserved.