簡體   English   中英

Powermock:如何模擬枚舉常量中的方法

[英]Powermock: How to mock a method in an enumeration constant

我有一個枚舉類型,我將其用作實現公共接口的其他對象的工廠集合。 代碼的簡化版本是:

interface Operation { 
    void execute();
}

enum Factory {
    TYPE1(Class1::new),
    TYPE2(Class2::new);

    private Supplier<Operation> constructor;

    Factory(Supplier<Operation> constructor) {
        this.constructor = constructor;
    }

    Operation build() {
        return constructor.get(); 
    }
}

客戶端代碼的簡化版本如下所示:

class Client {
    private void run(EnumSet<Factory> required) {
        for (Factory x : required) {
            x.build().execute(); 
        }
    }

    // Some code that calls run() with the right EnumSet
}

這一切似乎都按預期工作,所以我想編寫一些單元測試。

測試Factory很容易,但事實證明Client更困難。 問題是我不想開始調用Operation (他們做了很多工作)。 相反,我想讓x.build()返回一個模擬對象。

我已經嘗試使用 PowerMocks whenNew來捕獲Operation對象的創建,但這不起作用(我實際上沒有任何“新”操作)。 我也嘗試過使用 Powermock 'spy',但是這失敗了,因為枚舉常量是真實的對象。

有任何想法嗎?

兩種解決方案:

  • 你堅持使用 PowerMock(ito)。 那么簡單的問題是:您可能正在為測試准備錯誤的課程。 你必須調整那些枚舉常量,它們是內部類。 但這是可能的,例如,請參閱此答案
  • 你退后一步,改進你的生產代碼,使其更容易測試。

例如像這樣:

interface OperationProvider { 
    Operation build();
}

像這樣使用:

enum Factory implements OperationProvider {

現在你可以改變你的客戶端代碼來做

OperationProvider ourProvider = ...
whatever.build();...

關鍵是:在使用依賴注入時,您只需傳遞一個模擬的OperationProvider。 這意味着您基本上可以完全避免使用枚舉進行模擬的需要。 例如,您只需要確保在您的生產代碼中,您顯然在初始化ourProvider字段時傳遞了枚舉常量之一。

暫無
暫無

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

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