1.10 如何对抽象类进行单元测试:使用存根扩展? | Java Debug 笔记

970 阅读4分钟

本文正在参加「Java主题月 - Java Debug笔记活动」,详情查看 活动链接

Debug 笔记 <如何对抽象类进行单元测试:使用存根扩展?>

提问

我想知道如何对抽象类以及扩展抽象类的单元进行单元测试。

我是否应该通过扩展抽象类,对抽象方法进行存根测试,然后测试所有具体方法来测试抽象类?

然后只测试覆盖的方法,并在单元测试中测试扩展我的抽象类的对象的抽象方法?

我是否应该有一个抽象测试用例,可用于测试抽象类的方法,

并在我的测试用例中为扩展抽象类的对象扩展该类?

请注意,我的抽象类具有一些具体方法。

回答一:

编写一个Mock对象,并将其仅用于测试。它们通常非常非常非常小(从abstract类继承),而不是更多。然后,在单元测试中,您可以调用要测试的抽象方法。

您应该测试包含某些逻辑的抽象类,就像您拥有的所有其他类一样。

回答二:

有两种使用抽象基类的方式。

方案一:您正在专门化抽象对象,但是所有客户端都将通过其基本接口使用派生类。

方案二:您正在使用抽象基类来排除设计对象中的重复项,而客户端则通过其自己的接口使用具体的实现。

方案一的解决方案-策略模式

如果您遇到第一种情况,那么实际上您的派生类正在实现的抽象类中实际上有一个由虚拟方法定义的接口。

您应该考虑使其成为一个真实的接口,将抽象类更改为具体的,并在其构造函数中采用该接口的实例。然后,您的派生类将成为此新接口的实现。

这意味着您现在可以使用新接口的模拟实例并通过现在的公共接口测试每个新的实现,从而测试以前的抽象类。一切都很简单且可测试。

方案二的解决方案

如果您遇到第二种情况,则您的抽象类将作为帮助程序类工作。

看一下它包含的功能。查看是否可以将其中任何一个推入正在操作的对象上以最大程度地减少此重复。

如果还剩下什么,可以考虑将其作为一个帮助程序类,您的具体实现将其纳入其构造函数并删除其基类。

综上所述

通常

在复杂对象的简单网络上偏爱简单对象的复杂网络。

可扩展的可测试代码的关键是小的构建块和独立的布线。

回答三:

我对抽象类和接口所做的工作如下:

我编写了一个测试,使用了具体的对象。但是在测试中未设置类型X的变量(X是抽象类)。该测试类未添加到测试套件中,而是其子类,其子类具有将变量设置为X的具体实现的设置方法。

这样,我就不会重复测试代码。如果需要,未使用测试的子类可以添加更多测试方法。

回答四:

要专门针对抽象类进行单元测试,应出于测试目的,测试base.method()结果和继承时的预期行为而派生它。 您可以通过调用方法来测试方法,因此可以通过实现它来测试抽象类。

回答五:

如果您的抽象类包含具有商业价值的具体功能,那么我通常将通过创建对抽象数据进行存根的测试double或使用模拟框架为我执行此操作来直接对其进行测试。

我选择哪种方法在很大程度上取决于我是否需要编写特定于测试的抽象方法的实现。 我需要执行此操作的最常见情况是使用模板方法模式时,

例如,当我构建某种可扩展的框架以供第三方使用时。在这种情况下,抽象类定义了我要测试的算法,因此测试抽象库比特定实现更有意义。

但是,我认为重要的是,这些测试应仅关注真实业务逻辑的具体实现;您不应该对抽象类的实现细节进行单元测试,因为最终将导致脆弱的测试。

文章翻译自Stack Overflow :stackoverflow.com/questions/2…