PHPUnit、模拟接口和 instanceof

39
有时在我的代码中,我会检查特定对象是否实现了一个接口:
if ($instance instanceof Interface) {};

不过,在PHPUnit中创建该接口的模拟时,我似乎无法通过该测试。

 // class name is Mock_Interface_431469d7, does not pass above check
 $instance = $this->getMock('Interface'); 

我知道起名为Interface的类与实现Interface接口的类是不同的,但我不确定如何处理这个问题。

我必须模拟一个实现Interface接口的具体类吗?那样岂不是会失去使用接口实现可移植性的目的吗?

谢谢

3个回答

51

自3.5.0版本起,还有一个assertInstanceOf方法。

示例:

$this->assertInstanceOf('\Models\User', $this->userService->findById(1));

3
这是推荐的类型检查方法。 - Stephane Gosselin
1
除了@stefgosselin的答案,这是一种推荐的类型检查方式,因为它可以获得更好、自我解释的错误信息。将failed asserting that object is instance of Classfail asserting that false is true进行比较。 - Mike Doe
2
从PHP 5.5开始,您可以使用\Models\User::class代替'\Models\User',这使得重构变得更加容易。 - Vegard Larsen

44

这对我有用:

$mock = $this->getMock('TestInterface');
$this->assertTrue($mock instanceof TestInterface);

或许这是一个打字错误,或者 $instance 不是你想象中的那个变量?


12
没错,冷静的头脑最终战胜了情绪。经过一晚上的充分睡眠后,我意识到在模拟对象时没有使用完全限定的命名空间。 - Bryan M.
略有不同的用例,但我可以检查一个实例是一个类的实例还是该类的模拟。 - kapad
@kapad,你看,这就是多态的主要观点,你不需要知道当前对象是类的实例还是模拟对象。如果你仍然需要知道,那么你做错了什么。P.S. 只是提供信息,你可以使用 get_class 函数来获取对象的确切类名。 - Dmitry
@dvaffection 已经使用 get_class() 解决了。我想测试一下,但肯定做错了什么。关键是要检查一个边缘情况。 - kapad

1
使用PhpUnit函数assertInstanceOf。
示例:
$this->assertInstanceOf(ResponseInterface::class, $signInResponse);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接