PHPUnit和ZF2服务

PHPUnit和ZF2服务,php,zend-framework2,phpunit,zend-db,Php,Zend Framework2,Phpunit,Zend Db,我在使用PHPUnit创建测试时遇到了一个小问题 以下是我的设置: protected function setUp() { $serviceManager = Bootstrap::getServiceManager(); $this->mockDriver = $this->getMock('Zend\Db\Adapter\Driver\DriverInterface'); $this->mockConnection = $this->get

我在使用PHPUnit创建测试时遇到了一个小问题

以下是我的设置:

protected function setUp()
{
    $serviceManager = Bootstrap::getServiceManager();

    $this->mockDriver = $this->getMock('Zend\Db\Adapter\Driver\DriverInterface');
    $this->mockConnection = $this->getMock('Zend\Db\Adapter\Driver\ConnectionInterface');
    $this->mockDriver->expects($this->any())->method('checkEnvironment')->will($this->returnValue(true));
    $this->mockDriver->expects($this->any())->method('getConnection')->will($this->returnValue($this->mockConnection));
    $this->mockPlatform = $this->getMock('Zend\Db\Adapter\Platform\PlatformInterface');
    $this->mockStatement = $this->getMock('Zend\Db\Adapter\Driver\StatementInterface');
    $this->mockDriver->expects($this->any())->method('createStatement')->will($this->returnValue($this->mockStatement));
    $this->adapter = new Adapter($this->mockDriver, $this->mockPlatform);
    $this->sql = new Sql($this->adapter);

    $mockTableGateway = $this->getMock('Zend\Db\TableGateway\TableGateway', array(), array(), '', false);

    $maiFormuleRevisionTable = $this->getMockBuilder('Maintenance\Model\BDD\PMaiFormulerevisionTable')
        ->setMethods(array())
        ->setConstructorArgs(array($mockTableGateway, $this->adapter, $this->sql))
        ->getMock();
    $maiFormulerevisionService = $this->getMockBuilder('Maintenance\Service\Model\PMaiFormulerevisionService')
        ->setMethods(array())
        ->setConstructorArgs(array($maiFormuleRevisionTable))
        ->getMock();
    $this->assertTrue($maiFormulerevisionService instanceof PMaiFormulerevisionService);

    $this->controller = new RevisionsController($maiFormulerevisionService);

    $this->request    = new Request();
    $this->routeMatch = new RouteMatch(array('controller' => 'index'));
    $this->event      = new MvcEvent();
    $config = $serviceManager->get('Config');
    $routerConfig = isset($config['router']) ? $config['router'] : array();
    $router = HttpRouter::factory($routerConfig);
    $this->event->setRouter($router);
    $this->event->setRouteMatch($this->routeMatch);
    $this->controller->setEvent($this->event);
    $this->controller->setServiceLocator($serviceManager);
}
以下是对我的功能的测试:

public function testEditFormuleActionCanBeAccessed()
{
    $this->routeMatch->setParam('action', 'loadformule');
    $this->routeMatch->setParam('idformule', '23');
    $result   = $this->controller->dispatch($this->request);
    $response = $this->controller->getResponse();
    $this->assertEquals(200, $response->getStatusCode());
}
我的控制者:

public function loadformuleAction()
{
    try {
        $iStatus = 0;
        $iMaiFormuleRevisionId = (int) $this->params('idformule');

        $oFormule = $this->maiFormulerevisionService->selectByIdOrCreate($iMaiFormuleRevisionId);
        $maiFormulerevisionForm = new PMaiFormulerevisionForm($oFormule);

        if ($this->getRequest()->isPost()) {
            /* etc ... */
        }

        $viewModel = new ViewModel();
        $viewModel->setTerminal(true);
        $viewModel->setVariables([
            'maiFormulerevisionForm' => $maiFormulerevisionForm,
            'iMaiFormuleRevisionId'  => $oFormule->getMaiFormuleRevisionId(),
            'iStatus'                => $iStatus
        ]);
        return $viewModel;
    } catch (\Exception $e) {
        throw new \Exception($e);
    }
}
但是当我尝试运行测试时,它显示了一个错误,当我调用它($this->maiFormulerevisionService)时,我指出我的测试没有进入我的服务:

1) MaintenanceTest\Controller\RevisionControllerTest::TesteditFormuleAction可访问 异常:传递给Maintenance\Form\PMaiFormulerevisionForm::\uu construct()的参数1必须是Maintenance\Model\PMaiFormulerevision的实例,给定为null

我不明白为什么我的模拟不起作用

谢谢你的回答:)

编辑:

哼。。。当我尝试这个:

$maiFormulerevisionService = new PMaiFormulerevisionService($maiFormuleRevisionTable);
与此相反:

$maiFormulerevisionService = $this->getMockBuilder('Maintenance\Service\Model\PMaiFormulerevisionService')
            ->setMethods(array())
            ->setConstructorArgs(array($maiFormuleRevisionTable))
            ->getMock();

它进入服务,但不进入服务构造函数($maiFormuleRevisionTable)中指定的TableGateway。。。因此它仍然不起作用…

您设置了一个mock,但还必须设置调用方法
selectByIdOrCreate
时mock返回的内容。既然你这样做了:

$oFormule = $this->maiFormulerevisionService->selectByIdOrCreate($iMaiFormuleRevisionId);
$maiFormulerevisionForm = new PMaiFormulerevisionForm($oFormule);
只要不为此方法设置返回值,模拟将返回
selectByIdOrCreate
方法的
null

尝试添加类似以下内容的模拟方法:

$mock = $maiFormulerevisionService;
$methodName = 'selectByIdOrCreate';
$stub = $this->returnValue($maiFormuleRevisionTable);

$mock->expects($this->any())->method($methodName)->will($stub);

求你了,我真的被堵住了。我真的需要解决这个模拟问题,而且文档非常软!未测试,但看起来您正在为maiFormulerevisionService创建一个模拟,它为所有方法返回null。因此,在控制器中,这将返回null
$oFormule=$this->maiFormulerevisionService->selectByIdOrCreate($imaformulerevisionid)
这意味着构造函数中会传递null,这是您的错误消息
$maiFormulerevisionForm=new PMaiFormulerevisionForm($oFormule)我已测试,但测试模式下的方法实际上没有进入selectByIdOrCreate()函数,因此它不会返回null。。。事实上,它不涉及服务或datagateway类……在这里展示控制器的构造函数会很有用。