You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在setUp函数中使用Mock改写PHPUnit单元测试?

为Zend 2的NullMetricsClientFactory编写带Mock的PHPUnit测试

我目前有一个基础的PHPUnit测试,包含一个setUp方法和两个测试用例——还在学习PHPUnit,若有疏漏请多包涵:) 注:我使用的是Zend 2框架。我想给下面的测试加入Mock,但不知道具体怎么操作:

<?php

namespace AcmeTest\MetricsClient\Zend;

use Acme\MetricsClient\NullMetricsClient;
use Acme\MetricsClient\Zend\NullMetricsClientFactory;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceManager;

class NullMetricsClientFactoryTest extends \PHPUnit_Framework_TestCase
{
    private $serviceManager;
    private $factory;

    protected function setUp()
    {
        $this->factory        = new NullMetricsClientFactory();
        $this->serviceManager = new ServiceManager();
    }

    public function testIsZf2Factory()
    {
        $this->assertInstanceOf(FactoryInterface::class, $this->factory);
    }

    public function testCreatesNullMetricsClientService()
    {
        $nullClient = $this->factory->createService($this->serviceManager);
        $this->assertInstanceOf(NullMetricsClient::class, $nullClient);
    }
}

改造方案:引入Mock替代真实ServiceManager

单元测试的核心是隔离依赖,我们可以用PHPUnit的Mock功能替代真实的ServiceManager实例,避免创建完整服务管理器带来的额外开销,同时精准控制依赖行为。

修改后的测试代码:

<?php

namespace AcmeTest\MetricsClient\Zend;

use Acme\MetricsClient\NullMetricsClient;
use Acme\MetricsClient\Zend\NullMetricsClientFactory;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceManager;

class NullMetricsClientFactoryTest extends \PHPUnit_Framework_TestCase
{
    private $serviceManagerMock;
    private $factory;

    protected function setUp()
    {
        $this->factory = new NullMetricsClientFactory();
        
        // 创建ServiceManager的Mock实例,禁用原始构造函数
        $this->serviceManagerMock = $this->getMockBuilder(ServiceManager::class)
            ->disableOriginalConstructor()
            ->getMock();
    }

    public function testIsZf2Factory()
    {
        $this->assertInstanceOf(FactoryInterface::class, $this->factory);
    }

    public function testCreatesNullMetricsClientService()
    {
        // 调用工厂的createService,传入Mock的服务管理器
        $nullClient = $this->factory->createService($this->serviceManagerMock);
        
        $this->assertInstanceOf(NullMetricsClient::class, $nullClient);
    }
}

关键说明:

  1. 创建Mock实例:使用getMockBuilder(ServiceManager::class)构建Mock,disableOriginalConstructor()避免调用真实的ServiceManager构造函数(真实构造可能加载配置、初始化服务,这些在单元测试中不需要)。
  2. 替换真实依赖:把原来的真实ServiceManager实例换成Mock实例,实现依赖隔离。
  3. 扩展场景:如果后续NullMetricsClientFactory需要从ServiceManager获取其他服务(比如配置),可以给Mock添加方法预期,例如:
// 模拟ServiceManager返回指定配置数据
$this->serviceManagerMock->expects($this->once())
    ->method('get')
    ->with('Config')
    ->willReturn(['metrics' => ['enabled' => false]]);

这样就能测试工厂在不同配置下的行为。

内容的提问来源于stack exchange,提问作者Zabs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 23:10:22