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

PHP中如何mock可通过get_class检查的对象,命中switch对应case分支

问题根因

你通过createMock()生成的测试替身是MyFirstClass的动态匿名子类,get_class()会返回这个动态生成的mock类名(也就是你打印出来的Mock_MyFirstClass_c5f215a6),和字面量MyFirstClass::class的取值完全不一致,自然进不去对应分支。

解决方案

方案一:优化业务逻辑(推荐)

你的判断逻辑本身存在设计缺陷:get_class()是严格匹配类名,只要不是原类的直接实例(包括子类、mock类)都会匹配失败,违背了面向对象的里氏替换原则。建议修改为instanceof判断,既兼容现有继承结构,也能直接适配PHPUnit的mock对象:

public function sendMessage(MessageInterface $message) : void
{
    // 调整switch判断逻辑
    switch (true) {
        case $message instanceof MyFirstClass:
            $message->render();
            break;
        case $message instanceof MySecondClass:
            break;
        case $message instanceof MyThirdClass:
            break;
    }
}

修改后你原有的测试代码不需要做任何调整,就能正常命中分支、验证render()方法的调用。

方案二:不修改业务代码,仅调整测试用例

如果业务逻辑不允许改动,就必须使用MyFirstClass的直接实例,不能用任何子类(包括PHPUnit生成的mock类),否则get_class()永远匹配不上。你可以直接实例化原类,通过验证方法执行的副作用来判断分支是否命中:

public function testSendMessage() : void
{
    // 直接实例化原类,传入所需的构造依赖
    $message = new MyFirstClass(/* 填写构造参数 */);
    // 假设render方法会修改message对象的content属性,或产生其他可观测的副作用
    $originContent = $message->content;

    $this->myService->sendMessage($message);

    // 断言render的副作用已产生,即可证明进入了对应分支
    $this->assertNotEquals($originContent, $message->content);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 09:27:04