【发布时间】:2014-11-04 04:47:16
【问题描述】:
背景:我正在开发一个 MVC 框架以进行一些实践,并希望确保所有内容都经过 100% 单元测试。
当前的设置是拥有一个应用程序类的实例 (Ex_App)。主脚本向 Dispatcher/Router 询问控制器名称。此控制器名称是实现Ex_Controller 的类的名称。结果作为Ex_Dispatch_Result 的实例返回。使用invokeController($dispatchResult) 函数将此结果传递给Ex_App 实例。
这就是魔法发生的地方。下面的清单是摘录:
$controllerName = $dispatchResult->getControllerName();
... checks for validaty of class name ...
$controller = new $controllerName();
$controller->prepare($this);
我正在使用 PHPUnit 进行单元测试,并且能够模拟调度结果,正确检查验证控制器的类名是否有效。问题是如何检查是否调用了prepare。
我想做类似的事情:
$mockController = $this->getMockBuilder('Ex_Controller')
->setMockClassName('Invoke_Correct_Controller')
->getMock();
$mockController->expects($this->once())->method('prepare');
但是,由于在调用 invokeController 时会创建一个新的 Invoke_Correct_Controller 实例,因此它不会是这个模拟对象,因此 expects() 调用是完全不相关的。
我可以让Ex_Dispatch_Result 类负责返回一个控制器并对其进行测试,但是在返回一个实例之前,我需要验证类名的正确性,并且我认为应该由Ex_App 类负责而不是“哑壳”Ex_Dispatch_Result 类。
我在 PHPUnit 框架中是否缺少一些我可以用来测试代码的东西,或者一些可以在我的实例中工作的有用模式?我觉得传递控制器名称比从一开始就传递控制器实例要好得多,因为它需要初始化每个可能的控制器。所以,我有点想坚持传递名称并使用 Ex_App 作为控制器实例的工厂。
也许我只是在考虑这个问题的一部分,但有时会发生这种情况。这就是为什么第三方的新外观经常起作用的原因:-)
【问题讨论】:
标签: php unit-testing mocking phpunit