我正在尝试进行单元测试,但我还需要找到一块拼图。
我要做的是为以下代码编写测试。在这种情况下,我有一个非常简单的前端控制器(用 PHP 编写)。
class frontController
{
public function routeRequest($oRequest)
{
$sClassname = $oRequest->getController();
$sMethod = $oRequest->getAction();
$oController = new $sClassname();
$oResponse = $oController->{$sMethod}($oRequest);
return $oResponse;
}
}
我遇到的问题是因为代码创建了新对象。我可以轻松地模拟请求对象,以便我可以严格控制它在我的测试用例中实际执行的操作。我不确定用测试替身实际替换控制器的最佳方法。
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 的任何想法或建议表示赞赏,或者确实有任何替代方案。请记住 - 关键是关于如何测试一个对象,该对象本身会创建其他对象作为其执行的一部分。
谢谢!