Zend 框架 PhpUnit 测试错误由于在 null 上调用成员函数
Posted
技术标签:
【中文标题】Zend 框架 PhpUnit 测试错误由于在 null 上调用成员函数【英文标题】:Zend framework PhpUnit test error due to calling a member function on null 【发布时间】:2017-04-04 16:52:45 【问题描述】:你好,我是 phpunit 测试的新手,我被困在这里。
我已经学习了这个教程:Zend Framework 2 : Centralize phpunit test
之后我创建了一个模块测试
namespace ModulesTests\ServiceProvidersTest\Model;
use PHPUnit_Framework_TestCase;
use ModulesTests\ServiceManagerGrabber;
use User\Service\ServiceProvider;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorAwareTrait;
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\Adapter\Adapter;
use Zend\Db\Sql\Sql;
class TestServiceProviders extends PHPUnit_Framework_TestCase
protected $serviceManager;
protected $serviceprovider;
public function setUp()
$serviceManagerGrabber = new ServiceManagerGrabber();
$this->serviceManager = $serviceManagerGrabber->getServiceManager();
$this->serviceprovider = new ServiceProvider() ;
public function testSPdetails()
$stack = array('1','2');
$this->serviceprovider->getDetails($stack);
在我的 ServiceProvider 类中
namespace User\Service;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorAwareTrait;
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\Adapter\Adapter;
use Zend\Db\Sql\Sql;
class ServiceProvider implements ServiceLocatorAwareInterface
use ServiceLocatorAwareTrait;
public function getModel()
$em = $this->getServiceLocator()- >get('doctrine.entitymanager.orm_default');
return $em->getRepository('User\Entity\ServiceProvider');
public function getDetails($data = null,$fields='*')
$where = 1;
$company_ids = implode(',',$data);
if(isset($company_ids))
$where = 'sp.id IN('.$company_ids.')';
if(isset($fields))
$db = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
$query = 'some query';
.....Rest code.......
我收到此错误:
在 /opt/lampp/htdocs/project/module/User/src/User/Service/ServiceProvider.php 中调用成员函数 get()
请帮忙看看这里缺少什么..??
【问题讨论】:
自从我从 Zendframework2 迁移到 Zendframework3 后,我遇到了同样的问题 您应该知道 ServiceLocatorAwareInterface 已被弃用,很快就会从框架中删除,最好不要使用它:) 【参考方案1】:所以我在这里注意到了一些事情:
1:您没有显示任何代码来显示您如何将服务连接到服务管理器,因此尚不清楚这是否会起作用
2:当你需要使用你编写的服务管理器抓取器时,你直接实例化你的类
$this->serviceprovider = new ServiceProvider() ;
变成
$serviceManagerGrabber = new ServiceManagerGrabber();
$this->serviceManager = $serviceManagerGrabber->getServiceManager();
$this->serviceprovider = $this->serviceManager->get('YOUR_SERVICE_KEY');
3:您可能应该从单元测试开始,而不是那篇文章中解释的这些模块集成测试。见https://framework.zend.com/manual/2.3/en/modules/zend.test.phpunit.html
4:ServiceLocatorAwareInterface 已弃用,您可能应该使用工厂和服务管理器配置的工厂键来注入您的依赖项
5:你的代码似乎混合了学说和 zend db 我不知道你为什么这样做,但我的建议是......这是个坏主意
以下是您如何将其组合在一起的示例:
module.config.php
<?php
namespace Application;
return [
'service_manager' => [
'factories' => [
'ServiceProvider' => function ($serviceManager)
// This shouldn't be in this anon function, it should be its own
// factory but I'm lazy and already writing loads of code for this example
// @see https://framework.zend.com/manual/2.4/en/in-depth-guide/services-and-servicemanager.html#writing-a-factory-class
$service = new \Application\Service\ServiceProvider(
$serviceManager->get('doctrine.entitymanager.orm_default')
);
return $service;
,
]
],
];
ServiceProvider.php
<?php
namespace Application\Service;
use Doctrine\ORM\EntityManager;
class ServiceProvider
protected $entityManager;
public function __construct(EntityManager $entityManager)
$this->entityManager = $entityManager;
public function getModel()
return $this->entityManager- >getRepository('User\Entity\ServiceProvider');
public function getDetails($data = null, $fields='*')
$serviceProviderRepository = $this->entityManager->getRepository('User\Entity\ServiceProvider');
return $data;
模块测试
<?php
namespace ModulesTests\Application\Service;
use PHPUnit_Framework_TestCase;
use ModulesTests\ServiceManagerGrabber;
class ServiceProvidersTest extends PHPUnit_Framework_TestCase
protected $serviceManager;
protected $serviceprovider;
public function setUp()
$serviceManagerGrabber = new ServiceManagerGrabber();
$this->serviceManager = $serviceManagerGrabber->getServiceManager();
$this->serviceprovider = $this->serviceManager->get('ServiceProvider');
public function testSPdetails()
$stack = array('1','2');
$this->serviceprovider->getDetails($stack);
单元测试:
<?php
namespace ModulesTests\Application\Service;
use PHPUnit_Framework_TestCase;
use Application\Service\ServiceProvider;
use Prophecy\Argument;
class ServiceProvidersUnitTest extends PHPUnit_Framework_TestCase
protected $entityManager;
protected $serviceprovider;
public function setUp()
$this->entityManager = $this->prophesize("Doctrine\\ORM\\EntityManager");
$this->entityManager->getRepository(Argument::exact('User\Entity\ServiceProvider'))
->willReturn(true);
$this->serviceprovider = new ServiceProvider($this->entityManager->reveal());
public function testSPdetails()
$stack = array('1','2');
$this->serviceprovider->getDetails($stack);
$this->entityManager->getRepository(Argument::exact('User\Entity\ServiceProvider'))
->shouldHaveBeenCalledTimes(1);
【讨论】:
以上是关于Zend 框架 PhpUnit 测试错误由于在 null 上调用成员函数的主要内容,如果未能解决你的问题,请参考以下文章
PHPUNIT Zend 框架如何模拟 Zend_Registry::set 仅针对第一个数据源项进行测试并为第二个取消设置?
ZF2 / PHPUnit:模拟 Zend/Db/Adapter/Adapter 以供进一步使用
Jenkins 上的 Zend Framework 2 单元测试不起作用