簡體   English   中英

如何正確使用抽象類(測試問題)

[英]How to correctly use abstract classes (problems with testing)

我遇到了抽象類的一些問題,測試它們存在問題(代碼的公共部分沒有創建具體的實現),我想問應該如何正確解決這個問題。

我需要 class 代表我從 PLC 讀取的變量的當前狀態(我在這里使用觀察者模式),我還需要寫入其中一些變量。 我希望這部分獨立於連接(OPC UA,MODBUS ...)這就是為什么我創建 class PlcData代表我需要寫入或讀取的所有變量,這是一個抽象的 class,我想根據連接創建不同的實現類型 ( PlcDataOpcua , PlcDataModbus ...)

但是當我嘗試編寫單元測試時,我遇到了這個問題,我無法測試所有PlcData之間共享的公共代碼。

基於這里第二個最受好評的答案,我想出了這樣的事情: 在此處輸入圖像描述

但是因為Connection需要更新PlcData中的信息,所以它需要跟蹤PlcData實例。 對我來說,它比原來的解決方案更復雜,但它當然是“可測試的”。

誰能告訴我 go 的哪種方式或想出更好的解決方案?

您可以使用 Mockito 來測試抽象類: https://www.baeldung.com/junit-test-abstract-class

測試具體類可能是 go 的更好方法(編寫一個足夠通用的測試 class 以測試任一連接)

PLC 數據和連接類型現在以干凈的方式分離。 我經常看到像你原來的設計。 他們試圖通過繼承“常見情況”來實現可交換的功能。 一段時間后,他們變得非常混亂。

要使Connection能夠更新PlcData中的數據,您應該考慮觀察者模式,它使您能夠保持連接解耦。 這些連接將提供注冊“回調”的方法,這些回調將在某些 state 更改時調用。 如果數據量很小,可以在調用中傳遞,或者回調 function 將“轉身”並從連接中提取數據。

interface Connection {
    void registerLevelChange(Runnable callback);
}

class ModBusConnection implements Connection {
    private List<Runnable> levelChangeCallbacks = new ArrayList<Runnable>();

    public void registerLevelChange(Runnable callback) {
        levelChangeCallbacks.add(callback);
    }

    void processIncomingData() {
        if (level.hasChanged()) {
            for (var cb: levelChangeCallbacks) {
                cb.run();
            }
        }
    }
}

class PlcData {
    private Connection connection;

    void someMethod() {
        ...
        connection.registerLevelChange(() -> handleLevelChange());
        ...
    }    

    void handleLevelChange() {
        ...
    }
}

您還可以創建並行測試用例 class 層次結構。 在這里查看我的答案。

暫無
暫無

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

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