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

nnsrf1az  于 2023-05-05  发布在  Java
关注(0)|答案(1)|浏览(223)

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

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,但我面临两个问题:

  1. Mockito只允许每个线程有一个静态mock,所以如果我在一个规则中有多个客户端(类型A),这是不可行的。
    1.我不能使用这个来Assert异常,因为mockedConstruction使用了一个lambda函数,而像doThrow(someException).when(b).externalMethod()这样的操作会在mock创建本身而不是方法调用上给予异常。
    任何帮助都很感激。我道歉,如果语言不清楚或我错过了任何细节(请注明如果有的话)。
w46czmvw

w46czmvw1#

首先,我会尝试不使用模拟(如果可能的话)。例如,someException何时被b.externalMethod()抛出?也许你可以通过xy参数或一些测试配置来实现这一点:这将允许您进行无模拟测试。:)
如果这是不可能的,我会开始看这个类的设计,这使得它很难测试。你可以做的最简单的事情是使用依赖注入并添加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;
    }
    // ...
}

这样,在测试中,您就可以轻松地注入mock:
B mockedB = Mockito.mock(B.class);A testedA = new A(mockedB);
when(mockedB.externalMethod()).thenThrow(someException);
如果你不喜欢另一个公共构造函数的想法,你至少可以考虑一个包保护的构造函数。但总的来说,我认为第二个公共构造函数是可行的,如果你使用的是Lombok,你可以使用@RequiredArgConstructor

相关问题