【发布时间】:2010-12-16 06:59:32
【问题描述】:
我正在尝试单元测试,我还需要找到一块拼图。
我正在尝试为以下代码编写测试。在这种情况下,我有一个非常简单的前端控制器(用 PHP 编写)。
class frontController
{
public function routeRequest($oRequest)
{
$sClassname = $oRequest->getController();
$sMethod = $oRequest->getAction();
$oController = new $sClassname();
$oResponse = $oController->{$sMethod}($oRequest);
return $oResponse;
}
}
我遇到的问题是因为代码创建了新对象。我可以轻松地模拟请求对象,这样我就可以严格控制它在我的测试用例中实际执行的操作。我不确定用测试替身实际替换 控制器 的最佳方法。
This article from IBM 建议使用工厂方法来创建我的控制器,然后用用于测试的 特定 类覆盖它:
class frontController
{
public function routeRequest($oRequest)
{
$sMethod = $oRequest->getAction();
$oController = $this->createController($oRequest);
$oResponse = $oController->{$sMethod}($oRequest);
return $oResponse;
}
protected function createController($oRequest)
{
$sClassname = $oRequest->getController();
return new $sClassname();
}
}
然后进行测试可能是这样的:
class testFrontController extends frontController
{
public function setMockController($oMockController)
{
$this->oMc = $oMockController;
}
protected function createController($oRequest)
{
return $this->oMockController;
}
}
(注意这不是文章所说的,但我认为如果它这样做对我最有用)
另一种解决方案可能是让另一个类创建控制器。这将是 frontController 的依赖类。这样,我可以在测试期间用测试替身替换工厂/创建类。像这样的:
class frontController
{
public function routeRequest($oRequest, $oControllerFactory)
{
$sMethod = $oRequest->getAction();
$oController = $oControllerFactory->create($oRequest);
$oResponse = $oController->{$sMethod}($oRequest);
return $oResponse;
}
}
class controllerFactory
{
public function create($oRequest)
{
$sClassname = $oRequest->getController();
return new $sClassname();
}
}
我猜依赖注入可以在前端控制器构造函数中处理,也可以通过设置器而不是实际“路由”方法的参数来处理。
我认为我更喜欢选项 2。
这两种方法中的任何一种都是测试这类东西的正确方法吗?
(也许“好方法”在这里会更好!)
对选项 1 与选项 2 的任何想法或建议表示赞赏,或者确实有任何替代方案。请记住 - 关键是关于如何测试一个对象本身会创建其他对象作为其执行的一部分。
谢谢!
【问题讨论】:
标签: php unit-testing oop tdd phpunit