
phpunit 提供了 `self::identicalto()` 断言约束器,可替代自定义回调,实现对 mock 方法参数的严格引用相等(`===`)校验,确保传入的是同一对象实例而非仅值相等的对象。
在使用 PHPUnit 进行单元测试时,Mock 对象的参数验证是保障测试可靠性的关键环节。默认情况下,$mock->with($expected) 使用的是“值相等”(== 或对象属性比较)逻辑,这在面对对象实例时容易产生误判——例如,两个内容相同但不同内存地址的 Hosting 实例会被视为等价,导致本应失败的测试意外通过。
要强制执行严格引用比较(===),即要求传入参数必须是同一个对象实例,推荐使用 PHPUnit 内置的约束器 self::identicalTo():
$hosting = new Hosting();
$this->entityManager
->expects($this->once())
->method('persist')
->with(self::identicalTo($hosting)); // ✅ 严格引用匹配
$this->persister->persist($hosting); // 测试通过若被测代码中错误地创建了新实例(如 ->persist(new Hosting())),该断言将立即失败,并清晰提示:
Failed asserting that two variables reference the same object.
✅ 优势对比:
立即学习“PHP免费学习笔记(深入)”;
- ->with($hosting):触发 assertEquals 行为,可能调用 __toString()、比较属性等,非严格;
- ->with(self::callback(fn($x) => $x === $hosting)):功能正确但冗长,可读性差;
- ->with(self::identicalTo($hosting)):语义明确、简洁、原生支持、开箱即用。
⚠️ 注意事项:
- self::identicalTo() 属于 PHPUnit 的 Constraint(约束器) 体系,需配合 with() 使用,不可直接用于 assertEquals() 等断言函数;
- 它不仅适用于对象,也适用于 null、true、false、资源及所有标量类型,始终基于 === 判定;
- 确保使用的是 PHPUnit 9.5+(推荐)或至少 8.5+,该方法自较早版本已稳定存在,但文档中未在 with() 示例页突出展示,需查阅 Constraints 文档 或源码(PHPUnit\Framework\Constraint\IsIdentical)。
? 延伸技巧:
PHPUnit 还提供其他实用约束器,例如:
- self::equalTo($value) —— 值相等(默认行为)
- self::isInstanceOf(ClassName::class) —— 类型检查
- self::logicalAnd(...) / self::logicalOr(...) —— 组合条件
善用这些约束器,能让 Mock 验证更精准、测试意图更清晰,大幅提升测试的可维护性与可靠性。











