我想知道如何对抽象类以及扩展抽象类的类进行单元测试。
我是不是应该通过扩展抽象类,清除抽象方法,然后测试所有具体的方法来测试抽象类?然后只测试我覆盖的方法,并在单元测试中测试扩展抽象类的对象的抽象方法?
我是否应该有一个可用于测试抽象类的方法的抽象测试用例,并在我的测试用例中为扩展抽象类的对象扩展这个类?
注意,我的抽象类有一些具体的方法。
发布于 2008-10-28 13:50:25
编写一个Mock对象,并将其用于测试。它们通常是非常小的(继承自抽象类)并且不是more.Then,在你的单元测试中你可以调用你想要测试的抽象方法。
您应该测试包含一些逻辑的抽象类,就像您拥有的其他类一样。
发布于 2010-06-01 15:01:06
有两种使用抽象基类的方法。
针对1- Strategy Pattern的解决方案

如果您有第一种情况,那么您实际上拥有一个由您的派生类实现的抽象类中的虚方法定义的接口。
您应该考虑让它成为一个真正的接口,将您的抽象类更改为具体的,并在其构造函数中获取此接口的一个实例。然后,您的派生类将成为此新接口的实现。

这意味着您现在可以使用新接口的模拟实例以及通过now公共接口的每个新实现来测试以前的抽象类。一切都很简单,而且都是可测试的。
针对2个的解决方案
如果您有第二种情况,那么您的抽象类将作为帮助器类工作。

看看它包含的功能。看看是否可以将其推送到正在操作的对象上,以最大限度地减少这种重复。如果您还剩下什么,请考虑将它变成一个帮助器类,让您的具体实现在它们的构造函数中接受并删除它们的基类。

这再次导致了简单且易于测试的具体类。
作为规则的
支持简单对象的复杂网络,而不是复杂对象的简单网络。
可扩展可测试代码的关键是小的构建块和独立的连接。
更新:如何处理两者的混合?
有可能有一个基类同时执行这两个角色...ie:它有一个公共接口,并且有受保护的助手方法。如果是这种情况,那么您可以将助手方法分解为一个类(scenario2),并将继承树转换为策略模式。
如果您发现您的基类直接实现了一些方法,而其他方法是虚拟的,那么您仍然可以将继承树转换为策略模式,但我也认为这是一个很好的迹象,表明职责没有正确对齐,可能需要重构。
更新2:作为垫脚石的抽象类(2014/06/12)
前几天我遇到了一个使用抽象的情况,所以我想探讨一下为什么。
我们有一个标准的配置文件格式。这个特殊的工具有3个配置文件,都是这种格式。我希望每个设置文件都有一个强类型的类,这样,通过依赖注入,类就可以请求它所关心的设置。
我通过一个抽象基类来实现这一点,该类知道如何解析设置文件格式以及公开这些相同方法的派生类,但封装了设置文件的位置。
我可以编写一个由3个类包装的"SettingsFileParser“,然后委托给基类来公开数据访问方法。我选择不这样做,因为这将导致3个派生类中包含更多的委托代码。
然而..。随着代码的发展,这些设置类中的每一个的使用者都变得更加清晰。每个设置用户都会要求一些设置,并以某种方式转换它们(由于设置是文本,他们可能会将它们包装在对象中,或者将它们转换为数字,等等)。在这种情况下,我将开始将此逻辑提取到数据操作方法中,并将它们推回到强类型的设置类中。这将导致每一组设置的更高级别的接口,最终不再意识到它正在处理“设置”。
此时,强类型的设置类将不再需要"getter“方法来公开底层的”设置“实现。
在这一点上,我不再希望它们的公共接口包含设置访问器方法;因此,我将更改这个类以封装设置解析器类,而不是从它派生。
因此,Abstract类是我现在避免委托代码的一种方式,也是代码中提醒我以后更改设计的一个标记。我可能永远也到不了它,所以它可能会活一段时间...只有代码才能告诉我们。
我发现这对于任何规则都是正确的.比如“无静态方法”或“无私有方法”。它们表明代码中有异味。这很好。它让你寻找你错过的抽象...同时让你继续为你的客户提供价值。
我想像这样的规则定义了一个景观,在那里可维护的代码生活在山谷中。当你添加新的行为时,就像雨点一样落在你的代码上。最初你把它放在任何地方..然后,您可以重构以允许良好设计的力量推动行为,直到所有行为都在山谷中结束。
发布于 2008-10-28 13:47:35
我对抽象类和接口所做的工作如下:我编写了一个测试,它使用对象作为具体对象。但是X类型的变量(X是抽象类)没有在测试中设置。这个测试类没有添加到测试套件中,而是添加到测试套件的子类中,这些子类有一个设置方法,可以将变量设置为X的具体实现。这样我就不会重复测试代码。如果需要,not used测试的子类可以添加更多的测试方法。
https://stackoverflow.com/questions/243274
复制相似问题