模拟通过静态方法初始化的类

时间:2020-07-17 07:20:57

标签: java mockito

我有一个下面的类,该类具有通过静态方法初始化的对象“客户端”。 我不想使用Powermock并通过此静态方法对其进行初始化。 我希望使用Mockito模拟此调用=> client.rxQueryWithParams()。

这可能吗?尝试进行如下模拟,但我仍然输入client.rxQueryWithParams()调用 因此样机没有生效。

如果我只是自动连接SQLClient而不是在Spring之类的框架中,那会很好。无法做到这一点 在普通班上如下。如果相关的话,我可以模拟那个PostgreSQLClient.createShared()调用,但是似乎不能通过嘲笑来实现 并不想像所提到的那样介绍Powermock。有没有解决的办法?谢谢。

public class MainClass{
    private final SQLClient client;

    public MainClass(Vertx vertx, JsonObject config) {
        client = PostgreSQLClient.createShared(vertx, getData(config));
    }

    Single<ResultSet> insert(AddEventRequest request) {
        // some logic 
        return client.rxQueryWithParams(query, new JsonArray(params)); // I want to mock out this call. 
    }
}

测试

@ExtendWith(MockitoExtension.class)
public class MainClassTest {

    private TestSubscriber<Response> subscriber;
    private JsonObject configuration;
    private MainClass event;

    @Mock
    private SQLClient client;

    @BeforeEach
    public void init() {
        configuration = SomeStaticMethod.load();
        event = new MainClass(Vertx.vertx(), configuration);
        subscriber = new TestSubscriber<>();
    }

    @Test
    public void test() {
        Request request = getRequest(); // just a method creating an object with some values
        
        // this mock doesn't have any effect
        when(client.rxQueryWithParams(anyString(), any(JsonArray.class))).thenThrow(new RuntimeException());

        event.addEvent(request).subscribe(subscriber);
        subscriber.assertCompleted();
        subscriber.assertNoErrors();
    }
}

3 个答案:

答案 0 :(得分:1)

没有PowerMock或类似工具是不可能的。

答案 1 :(得分:1)

从Mockito 3.4开始提供模拟静态方法。

请参阅拉取请求:Mockito #1013: Defines and implements API for static mocking.

请注意,此功能可用并不等同于建议使用它。它针对无法重构源代码的旧版应用程序。

您最好将MainClass重构为在构造函数中接受SQLClient参数。如果需要最大程度地减少对代码的影响,则可以添加其他委派的构造函数。

说过:

try (MockedStatic<PostgreSQLClient> postgreSQLClientStatic = Mockito.mockStatic(PostgreSQLClient.class)) {
    postgreSQLClientStatic.when(() -> PostgreSQLClient.createShared(any(), any())).thenReturn(client);
    // NOTE: I create the event when mocked PostgreSQLClient is in scope
    MainClass event = new MainClass(Vertx.vertx(), configuration);
    when(client.rxQueryWithParams(anyString(), any()))
        .thenThrow(new RuntimeException("exception from mock"));
    event.insert(request);
}

答案 2 :(得分:-1)

您可以通过打包在org.springframework.test.util下的ReflectionTestUtils将模拟实例注入MainClass实例

  ReflectionTestUtils.setField(event , "client", client);