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
相关产品推荐
相关产品推荐

