我正试图让我的头部单元测试,还有一件我需要找到的拼图.
我要做的是为以下代码编写测试.在这种情况下,我有一个非常简单的前端控制器(用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的依赖类.这样我就可以在测试过程中用test double替换工厂/创建类.像这样的东西:
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();
}
}
我想依赖注入可以在前端控制器构造函数中处理,或者通过setter而不是实际“route”方法的参数来处理.
我想我更喜欢选项2.
这两种方法中的任何一种都是正确的测试方法吗?
(也许“好方法”会更好的在这里!)
关于选项1与选项2的任何想法或建议都表示赞赏或确实有任何替代方案记住 – 关键是如何测试一个对象本身创建其他对象作为其执行的一部分.
谢谢!
解决方法:
我通常认为工厂在这种情况下是一件好事.除了可交换性方面,它还意味着工厂可以存储正在创建的对象所需的其他参数,数据或依赖项,因此实际请求新对象的对象不必知道任何有关它们的信息. ..
标签:php,oop,unit-testing,tdd,phpunit
来源: https://codeday.me/bug/20190607/1192122.html