Php 如何对Zend控制台提示符进行单元测试。单元测试当前正在等待用户响应
我正在使用zend 2.2和zend/console创建cli脚本。该脚本提示用户使用以下代码输入名称或电子邮件地址等信息Php 如何对Zend控制台提示符进行单元测试。单元测试当前正在等待用户响应,php,zend-framework,phpunit,Php,Zend Framework,Phpunit,我正在使用zend 2.2和zend/console创建cli脚本。该脚本提示用户使用以下代码输入名称或电子邮件地址等信息 $name = Line::prompt('Enter Name: ', false, 100); 当用户正在使用脚本时,这可以正常工作 我的问题是尝试对其进行单元测试。此时,当我在单元测试中调用dispatch时,它只是挂起并等待用户输入响应。显然这是个问题 我的代码是: public function testCliScript() { $console
$name = Line::prompt('Enter Name: ', false, 100);
当用户正在使用脚本时,这可以正常工作
我的问题是尝试对其进行单元测试。此时,当我在单元测试中调用dispatch时,它只是挂起并等待用户输入响应。显然这是个问题
我的代码是:
public function testCliScript()
{
$consoleMock = $this->getConsoleMock();
$consoleMock->expects($this->any())->method('writeLine');
$this->dispatch('run cli--name=test --email=test@example.com');
}
这最终需要
protected function getName()
{
$name = $this->getRequest()->getParam('name');
$nameOk = !empty($name);
while (!$nameOk) {
$nameOk = false;
$name = Line::prompt('Enter Name: ', false, 100);
// tie into filter
if (strlen($name) < 1) {
$this->getConsole()->writeLine('Name is Too Short');
continue;
}
$nameOk = true;
};
return $name;
}
受保护的函数getName()
{
$name=$this->getRequest()->getParam('name');
$nameOk=!空($name);
while(!$nameOk){
$nameOk=false;
$name=Line::prompt('entername:',false,100);
//接入滤波器
if(strlen($name)<1){
$this->getConsole()->writeLine('名称太短');
继续;
}
$nameOk=true;
};
返回$name;
}
如果有人对如何测试这一点有任何建议,我们将不胜感激
谢谢这是可测试性的主要论点之一 prompt对象是SUT的硬依赖项,因此,要正确测试SUT,需要将两者解耦 通过构造函数使用的示例:
// uses omitted for brevity
class SomeController extends AbstractConsoleController
{
protected $namePrompt;
public function __construct(PromptInterface $namePrompt)
{
$this->namePrompt = $namePrompt;
}
protected function getName()
{
// etc etc
$name = $this->namePrompt->show();
}
}
因此,您可以在测试中插入提示模拟:
// uses omitted for brevity
class SomeControllerTest extends TestCase
{
protected $controller;
protected $namePromptMock;
public function setUp()
{
// etc etc
$this->namePromptMock = $this->getMock(PromptInterface::class);
$this->controller = new SomeController($this->namePromptMock);
// etc etc
}
public function testSomeAction()
{
$this->namePromptMock->expects($this->atLeastOnce())
->method('show')
->willReturn('a fake name');
// dispatch, assertions on the response, etc etc
}
}
还有其他方法可以实现依赖项反转,即在这种情况下,控制器可能需要一大堆提示,因此,您可以使用一个小型插件管理器作为服务定位器,或者使用某种工厂,而不是注入每个提示实例(这既不方便又难看),您可以很容易地模拟这种抽象,这样当被询问时,它只会返回提示模拟