我可以用 PHPUnit 模拟接口实现吗?

Posted

技术标签:

【中文标题】我可以用 PHPUnit 模拟接口实现吗?【英文标题】:Can I mock an interface implementation with PHPUnit? 【发布时间】:2013-09-29 03:43:23 【问题描述】:

我有一个我想模拟的界面。我知道我可以模拟该接口的实现,但是有没有办法只模拟该接口?

<?php
require __DIR__ . '/../vendor/autoload.php';

use My\Http\IClient as IHttpClient;  // The interface
use My\SomethingElse\Client as SomethingElseClient;


class SomethingElseClientTest extends PHPUnit_Framework_TestCase 
  public function testPost() 
    $url = 'some_url';
    $http_client = $this->getMockBuilder('Cpm\Http\IClient');
    $something_else = new SomethingElseClient($http_client, $url);
  

我在这里得到的是:

1) SomethingElseTest::testPost
Argument 1 passed to Cpm\SomethingElse\Client::__construct() must be an instance of
My\Http\IClient, instance of PHPUnit_Framework_MockObject_MockBuilder given, called in
$PATH_TO_PHP_TEST_FILE on line $NUMBER and defined

有趣的是,PHPUnit, mocked interfaces, and instanceof 会建议这可能有效。

【问题讨论】:

您误读了另一个问题,它使用的是-&gt;getMock() 而不是-&gt;getMockBuilder(),就像您一样,您也找到了问题的答案。但是 IIRC 确实存在您的问题的副本,但我现在找不到。 有趣。我在搜索中找不到它。感谢您的编辑。 您也可以在下面接受您的回答,以便您的问题被标记为已回答。 好电话。似乎这里没有更多的输入。谢谢。 【参考方案1】:

代替

$http_client = $this->getMockBuilder(Cpm\Http\IClient::class);

使用

$http_client = $this->getMock(Cpm\Http\IClient::class);

$http_client = $this->getMockBuilder(Cpm\Http\IClient::class)->getMock();

完全有效!

【讨论】:

我不得不 $mockBuilder->setMethods(['all','my','interface','methods']) 让它工作。但是,是的,工作完美。感谢您的帮助。 只有 $this->getMockBuilder(...)->getMock() 为我工作 PHPUnit 7.5.1【参考方案2】:

以下对我有用:

$myMockObj = $this->createMock(MyInterface::class);

【讨论】:

【参考方案3】:
$http_client = $this->getMockBuilder(Cpm\Http\IClient::class)
                    ->setMockClassName('SomeClassName')
                    ->getMock();

setMockClassName() 在某些情况下可用于解决此问题。

【讨论】:

以上是关于我可以用 PHPUnit 模拟接口实现吗?的主要内容,如果未能解决你的问题,请参考以下文章

在 PHPUnit 中实现给定接口的模拟对象上的未定义方法?

学习phpunit

phpunit必须是可遍历的或实现接口Iterator

PHPUnit 4.8 Mock mysql 数据库接口

PHPUnit:使用注解返回特定类型真的有必要吗?

C#为啥接口可以实例化一个实现该接口的类?