
phpunit 提供 `identicalto()` 断言约束器,可严格按 `===` 语义匹配传入 mock 方法的**同一对象实例**,避免因新建相同类型对象导致误通过,比手动写 `callback` 更简洁、语义更清晰。
在单元测试中,当需要确保被测代码向依赖(如 Doctrine EntityManager)传递的是完全相同的对象引用(而非仅属性相等的另一个实例),仅靠默认的 with($hosting) 是不够的——它使用松散的 == 比较逻辑(或对象属性遍历),无法区分 $hosting 和 new Hosting()。这会导致测试“侥幸通过”,丧失对对象生命周期和引用一致性的保障。
幸运的是,PHPUnit 内置了专用于严格引用比较的约束器:self::identicalTo($expected)。它底层直接使用 === 运算符进行判断,精准匹配对象身份(identity),而非状态(state)。
✅ 正确用法示例:
$hosting = new Hosting();
$this->entityManager
->expects($this->once())
->method('persist')
->with(self::identicalTo($hosting)); // ✅ 严格引用匹配
$this->persister->persist($hosting); // 测试通过❌ 若内部错误地创建新实例:
立即学习“PHP免费学习笔记(深入)”;
// EntityManager::persist() 内部误写为:
public function persist($object) {
$this->doSomething(new Hosting()); // ❌ 错误:传入新实例
}此时测试将明确失败,提示类似 Expected argument of type "identicalTo(
? 其他实用约束器(同属 PHPUnit\Framework\Constraint):
- self::equalTo($value) —— 松散相等(==)
- self::isInstanceOf($className) —— 类型检查
- self::logicalAnd(...), self::logicalOr(...) —— 组合条件
- self::contains($needle) —— 数组/Traversable 包含检查
? 提示:identicalTo() 也适用于 null、资源、标量(如 identicalTo(0) 与 identicalTo('0') 不同),是编写高保真集成契约测试的关键工具。请优先选用内置约束器,避免重复造轮子式的匿名回调。











