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

如何在PHPUnit中模拟被测方法内创建的其他类对象

使用PHPUnit模拟依赖对象测试sourceClass::myFunction()

你的问题太常见了——当代码里硬编码创建依赖对象时,测试逻辑完全被外部依赖牵着走,根本没法稳定验证自己的业务逻辑。解决这个问题的核心思路是让依赖可替换,再配合PHPUnit的Mock功能来控制依赖的行为,具体可以这么操作:

第一步:改造原类,支持依赖注入

首先得把sourceClass里直接new otherClass()的写法改掉,换成依赖注入(这里用构造函数注入为例,是最常用也最清晰的方式):

class sourceClass{
    private $otherClass;

    // 通过构造函数传入otherClass实例,而非自行创建
    public function __construct(otherClass $otherClass){
        $this->otherClass = $otherClass;
    }

    function myFunction(){
        // 现在使用注入的对象,不再硬编码创建
        if($this->otherClass->someMethod() == 'want to controll it'){
            return 'want this to get';
        }
    }
}

这么改的好处很明显:生产环境可以传入真实的otherClass实例,测试环境则能轻松替换成Mock对象,完全掌控依赖的行为。

第二步:编写带Mock的测试用例

接下来在PHPUnit测试中,创建otherClass的Mock对象,强制它的someMethod返回你预设的值,这样就能精准控制myFunction的执行路径:

class StubTest extends TestCase{
    function testMyFunction(){
        // 1. 创建otherClass的Mock实例
        $mockOther = $this->createMock(otherClass::class);

        // 2. 指定规则:当调用someMethod时,返回我们想要的字符串
        $mockOther->method('someMethod')
                  ->willReturn('want to controll it');

        // 3. 把Mock对象注入到sourceClass实例中
        $source = new sourceClass($mockOther);

        // 4. 断言结果符合预期
        $this->assertEquals('want this to get', $source->myFunction());
    }
}

特殊情况:没法修改原类怎么办?

如果因为某些限制不能改动sourceClass的代码(比如是第三方类库),可以用一个偏hack的应急方案——利用PHP反射替换类内的私有属性,但这种方式破坏了类的封装性,只建议临时使用:

function testMyFunctionWithoutModifyingSource(){
    $source = new sourceClass();
    
    // 创建Mock对象
    $mockOther = $this->createMock(otherClass::class);
    $mockOther->method('someMethod')->willReturn('want to controll it');

    // 用反射获取sourceClass里的$other_object属性
    $reflection = new ReflectionClass($source);
    $property = $reflection->getProperty('other_object');
    $property->setAccessible(true);
    // 把Mock对象赋值进去
    $property->setValue($source, $mockOther);

    // 执行断言
    $this->assertEquals('want this to get', $source->myFunction());
}

当然,还是优先推荐改造原类实现依赖注入,这是更健壮、可维护的代码设计思路。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:37:30