【问题标题】:How to correctly use abstract classes (problems with testing)如何正确使用抽象类(测试问题)
【发布时间】:2021-02-22 14:22:12
【问题描述】:

我遇到了抽象类的一些问题,就是测试它们有问题(代码的公共部分没有创建具体实现),我想问应该如何正确解决这个问题。

我需要有一个类来表示我从 PLC 读取的变量的当前状态(我在这里使用观察者模式),并且我还需要写入其中的一些变量。我希望这部分独立于连接(OPC UA,MODBUS ...)这就是为什么我创建了类PlcData,它代表我需要写入或读取的所有变量,这是一个抽象类,我想创建基于不同的实现关于连接类型(PlcDataOpcuaPlcDataModbus ...)

但是当我尝试编写单元测试时,我遇到了这个问题,我无法测试所有PlcData 之间共享的公共代码。

基于第二个最受好评的答案here 我想出了这样的事情:

但是因为Connection 需要更新PlcData 中的信息,它需要跟踪PlcData 实例。对我来说,它比原来的解决方案更复杂,但它当然是“可测试的”。

谁能告诉我该走哪条路或想出更好的解决方案?

【问题讨论】:

  • 对扩展抽象类的具体类进行单元测试有什么问题?

标签: java unit-testing design-patterns junit


【解决方案1】:

PLC 数据和连接类型现在以干净的方式分离。我经常看到像你原来的设计。他们试图通过继承“常见情况”来实现可交换的功能。一段时间后,它们变得非常混乱。

要使Connections 能够更新PlcData 中的数据,您应该考虑观察者模式,它使您能够保持连接解耦。这些连接将提供注册“回调”的方法,这些回调将在某些状态更改时被调用。如果数据量很小,可以在调用中传递,或者回调函数“转身”从连接中拉取数据。

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() {
        ...
    }
}

【讨论】:

  • 嗨,我同意你的观点,分离连接更好,但你提出的不适用于我的问题。我将创建新问题如何正确实现它并将其链接到此处如果您可以检查我的问题并在那里帮助我,这真的对我有帮助。
  • 这是我更新的问题link
【解决方案2】:

您可以使用 Mockito 来测试抽象类: https://www.baeldung.com/junit-test-abstract-class

测试具体的类可能是更好的方法 (编写一个足够通用的测试类来测试任一连接)

【讨论】:

  • 嗨,我已经阅读了这篇文章,但我对它没有什么问题。根据我发布的链接,它看起来不是“好习惯”,最大的问题是它对我不起作用,我的方法改变了内部变量,它似乎不适用于 mockito(测试以空指针异常结束)现在我创建了匿名类,它使应该被覆盖的方法留空(这可行,但不好)我还想知道什么是正确的(基于最佳实践)colution。
【解决方案3】:

您还可以创建并行测试用例类层次结构。看我的回答here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-01
    • 2011-07-13
    • 2015-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-08
    相关资源
    最近更新 更多