单元测试一个过大的前端控制器类:最佳策略

时间:2016-09-06 11:39:33

标签: unit-testing phpunit

我有一个Web应用程序,它当前作为包含前端控制器的单个大型类存在,以及一个运行该类并传入设置的引导程序文件。

随着时间的推移,这个类已经变得过于庞大,有多个问题,我一直想重构为更明显的子类。我对各种重构非常熟悉。

但是,对于这个应用程序,目前还没有测试覆盖率。因为所有交互都是通过读取GET和POST参数来完成的,所以系统中只有一种公共方法,即通过前端控制器入口点进行的这种URL交互。所以这个类很难进行单元测试(我将使用PHPUnit)。

显然,通过已有的测试进行重构会更加安全。所以我欢迎对哪种策略最好的看法:

1)根据使用Web应用程序的用户创建一堆实现GET和POST交互的测试;或

2)使用ReflectionClass workaround对私有函数创建一堆测试,并将这些测试与重构同时转换为标准PHPUnit测试;或

3)在进行子类重构后添加单元测试,测试公共入口API指向新的子类。

1 个答案:

答案 0 :(得分:0)

无论你如何接近它,如果可以的话,我会一次只做一个功能,它会让任务变得不那么令人生畏,因此更容易实现......

过去遇到过这种情况(实际上是很多次),我通常会这样做:

首先,应用程序是否使用外部依赖项,如数据库?首先,我们需要使这些可预测。我通常会尝试找到创建这些外部依赖项的位置,然后将其委托给一个良好的依赖注入框架(如Pimple)。

完成后,您可以根据设置的条件向DI工厂方法添加规则以返回测试数据库:我通常使用测试域,因此如果站点是foo.local,那么我还有域测试.foo.local设置(例如在Apache配置中)环境变量APPLICATION_ENV设置为'tests'。然后,DI容器可以检查此环境变量以提供正确的依赖关系,在我们的示例中是指向测试数据库的连接。

(它不喜欢生产代码知道它可能在测试场景中,但它是一个较小的邪恶,它可以通过使用在文件名中具有环境变量的配置文件来缓解。我离题了。)

当这样做时,在我的测试中,我接着引用了相同的测试数据库,然后我用它来设置一些可预测的测试数据,例如DbUnit或test-db-acle(免责声明,我写了后者一,所以我倾向于那。)

一旦测试数据到位,我就会向Guzzle(在各种重要变体中)发出请求,并记录输出,然后我用它来进行设置行为的测试'在石头'。 注意:这是一种非常不精确的方法,测试的最佳方式是以测试驱动的方式,但在这种情况下这显然不是解决方案。 但是,如果您确定已经对此进行了一些手动测试,那么这是至少进行一些烟雾测试的好方法。根据我的经验,即使进行了一次基本的烟雾测试,其价值也远远超过没有任何基本烟雾测试的价值。

现在您已经进行了烟雾测试,您可以重构应用程序的这一部分并转移到新的应用程序。

我希望这有帮助......