[英]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.