1

我是 PHP 测试的新手,正在尝试使用 TDD 构建一个简单的项目。

简单的想法是制作某种简单的卡片/甲板设置。

我开始编写测试,并迅速开始从我失败的测试中混搭CardDeck类和CardStack类。他们都实现了一些相同的方法,比如 getTop()、getTopStack().. 所以我决定实现一个CardDeckInterface,一个抽象类BaseCardStack来干掉它。

重构之后。CardDeck 和 CardStack 扩展了实现 CardStackInterface 的 BaseCardStack。

CardDeck 和 CardStack 的唯一区别在于 CardStack 的构造和一些附加功能。否则,BaseCardStack 中的任何已实现功能都不会被覆盖。

这就是我的麻烦所在。在我的CardDeckTest 中,我进行了与已实现方法相关的测试,这些方法已移动 BaseCardDeck。

我是否应该将当前的测试保留在 CardDeckTest 中(它们仍然像以前一样通过)并为 CardStackTest 编写一组额外的测试?这似乎是错误的解决方案,因为这些方法已经过测试并且没有任何不同(没有被覆盖),正如我所提到的,BaseCardStack 中实现的方法没有被覆盖。

相反,我认为我应该为我的抽象类移动/编写测试。

基本上我想测试我的抽象类中的函数,我知道这些函数将被实现而不会被覆盖。

但是我该怎么做呢?我应该嘲笑吗?我应该改变我的模式吗?

4

1 回答 1

1

相反,我认为我应该为我的抽象类移动/编写测试

实际上,您可能希望在实现该接口的任何其他类上应用相同的单元测试集。

但在你做一些警告之前:三思而后行。您可能不需要这里的抽象类。听起来您有某种数据结构非常适合两个类使用的工作,但是这两个类不是那种数据结构。

但是,通过从抽象数据结构类扩展这两个类,您实际上只是使这两个类非常具有这种数据结构。

最喜欢的组合胜过继承

只是说,对于您关于如何测试抽象类的原始问题,您可以从中创建一个测试替身。这可以与能够模拟抽象类(和测试抽象类)的 PHPUnit 模拟一起使用,同时接管定义的方法。

但是我通常只是创建一个用于测试的存根类,它正在创建一个新文件,该文件包含一个从抽象基类扩展的类定义,该类定义在其他方面独立于应用程序的其余部分(但绑定在抽象类上),然后使用它作为单元测试中的主题(与带有 PHPUnit 的抽象类的测试方法进行比较)。

这样做通常不会隐藏在复杂的模拟和存根设置之后不需要抽象基类的事实。只需编写尽可能少的代码,这是很难实现的。

希望这会有所帮助,请随时回问。

哦,实际上这里是另一个提示。我为抽象基类所做的一两次是创建一个包含基类测试的抽象测试用例。然后从它扩展为具体的实现测试确实工作得很好。IIRC的相关问题是:

于 2013-09-29T08:40:24.887 回答