试图模拟一个类,使其不会在 phpUnit 中执行构造函数

Posted

技术标签:

【中文标题】试图模拟一个类,使其不会在 phpUnit 中执行构造函数【英文标题】:Trying to mock a class so it won't execute constructor in phpUnit 【发布时间】:2021-12-17 05:38:05 【问题描述】:

我正在测试一个控制器,该控制器拥有一个对象,每次我进行测试时都会在其构造函数中引发异常,因为构造函数检查某些环境变量不为空(但在测试期间它们为空)。我尝试使用 getMockBuilder()->disableOriginalConstructor()、createMock、Mockery::mock()->makePartial() 模拟该类,我尝试在调用 parent::setUp 之前和之后在 setUp() 中执行它,我尝试执行单元测试中的所有内容而不是 setUp(),它们都执行构造函数,我不明白为什么!

这是一个测试示例:

public function setUp(): void

   self::$mockClient = $this->createMock('App\Helpers\Client');
   parent::setUp();


public function testSuccessfullyPost()

   $input_data = [
      'name' => 'valid name',
      'email' => 'valid@email.com'
   ];

   $this->json('POST', $this->testUri, $input_data, ['authentication' => $this->getToken()]);
   $this->seeStatusCode(201);

有人有想法吗?

我正在使用 phpUnit 9.5.10

【问题讨论】:

【参考方案1】:

我过去使用过以下内容:

$this->mockSchema = $this->getMockBuilder('Drupal\sqlsrv\Driver\Database\sqlsrv\Schema')
      ->setMethods(['getDefaultSchema', '__construct'])
      ->setMockClassName('MockSchema')
      ->setConstructorArgs([NULL])
      ->disableOriginalConstructor()
      ->getMock();
$this->mockSchema->method('getDefaultSchema')->willReturn('dbo');

如果禁用原构造函数,我觉得还是需要“设置方法”来阻止父构造函数执行。

【讨论】:

以上是关于试图模拟一个类,使其不会在 phpUnit 中执行构造函数的主要内容,如果未能解决你的问题,请参考以下文章

来自另一个类的 PHPUnit 模拟方法

我可以在PHPUnit中“模拟”时间吗?

Phpunit 在测试类中仅模拟一种方法 - 使用 Mockery

在 Laravel 4 中使用 Mockery 模拟自定义类

如何在 PHPUnit 中跨多个测试模拟测试 Web 服务?

为啥我在测试创建相同类的 phpUnit 静态方法后得到“无法加载模拟 MyClassConsumer,类已存在”?