簡體   English   中英

模擬由 static 方法初始化的 class

[英]Mock a class initialised by a static method

我有以下 class 它有一個由 static 方法初始化的 object '客戶端'。 我不想使用 Powermock 並讓它通過這個 static 方法初始化。 我希望使用 mockito 來模擬這個調用 => client.rxQueryWithParams()。

這可能嗎? 嘗試如下模型,但我仍然輸入 client.rxQueryWithParams() 調用,因此模型沒有生效。

如果我只是在 Spring 之類的框架中自動裝配了 SQLClient,這會很好笑。 在正常的 class 中無法實現這一點,如下所示。 如果相關,我可以模擬 PostgreSQLClient.createShared() 調用,但它似乎無法通過 mockito 實現,並且不希望像提到的那樣引入 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();
    }
}

沒有 PowerMock 或類似工具是不可能的。

Mocking static 方法自 Mockito 3.4 起可用。

請參閱拉取請求: Mockito #1013:為 static ZD1892D0BDD8378 定義和實現 API。

請注意,此功能可用的事實並不等同於使用它的建議。 它針對無法重構源代碼的遺留應用程序。

您最好重構 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);
}

您可以通過 org.springframework.test.util 下打包的 ReflectionTestUtils 將模擬實例注入 MainClass 實例

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM