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 以供进一步使用

zend framwork黑箱测试

Jenkins 上的 Zend Framework 2 单元测试不起作用

在 catch 块中设置对象属性时 PHPUnit 测试失败

带有 Zend Framework 2 模块的 PHPUnit