2014-11-04 17 views
0

背景:我正在为一些练习开发MVC框架,并希望确保所有内容都经过100%单元测试。模拟动态分配实例上的方法?

安装程序目前有一个应用程序类的实例(Ex_App)。主脚本向分派器/路由器请求控制器名称。此控制器名称是实施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的做我的单元测试,并且我能够嘲笑调度结果,正确地检查验证控制器工作的类名。问题是如何检查是否准备被调用。

我想要做类似的东西:

$mockController = $this->getMockBuilder('Ex_Controller') 
    ->setMockClassName('Invoke_Correct_Controller') 
    ->getMock(); 
$mockController->expects($this->once())->method('prepare'); 

但是由于Invoke_Correct_Controller一个新的实例在调用invokeController创建的,也不会是这个模拟,因此expects()通话是完全不相干的。

我可以使Ex_Dispatch_Result类负责返回控制器和测试,但返回一个实例之前,我需要验证在我看来,这个责任应该与Ex_App类,而不是类名和正确性“哑贝”Ex_Dispatch_Result班。

在PHPUnit框架中是否存在我可以用来测试代码的东西,还是可以在我的实例中工作的一些有用模式?我感觉从控制器名称的缩放方式传递的方式要比从一开始就传递控制器实例的方式更好,要求初始化每个可能的控制器。所以,我想坚持传递名称并使用Ex_App作为控制器实例的工厂。

也许我只是过度思考这个问题的一部分,但有时会发生这种情况。这就是为什么新的眼光看待第三方经常工作:-)

回答

2

有几件事情你可以做:

  • 提取控制器创建的逻辑,以单独的类如ControllerFactory,然后模拟控制器工厂实例,以便它返回您的$ mockController。
  • 提取控制器创建逻辑来分离方法并使用部分模拟。
  • 从$ dispatchResult-> getControllerName()返回$ mockController,这可能需要模拟$ dispatchResult或甚至其他东西。

如果你想要更详细的答案,请提供更多的类和方法的代码示例。