php - 在单元测试中模拟被测试的对象是不是很糟糕?

标签 php unit-testing phpunit

这是我正在单元测试的类。目前我正在测试 doSomething 函数:

class FooClass {
  public function doSomething( $user ) {
    $conn = $this->getUniqueConnection( $user->id );
    $conn->doSomethingDestructive();
  }

  private function getUniqueConnection( $id ) {
    return new UniqueConnection( $id );
  }
}

如您所见,doSomething 函数根据它接收的参数的属性获取 UniqueConnection 的新实例(我未在此处测试的类)。问题是 UniqueConnection::doSomethingDestructive 方法是我无法在测试期间调用的方法,因为它...具有破坏性。所以我想 stub /模拟 UniqueConnection 而不是使用真实的。

我没有看到任何方式来注入(inject)我模拟的 UniqueConnection。我会让 UniqueConnection 成为 FooClass 的构造函数参数,但是,如您所见,会根据 doSomething 的参数创建一个新参数函数和它可能被调用的所有唯一 ID 都无法提前知道。

我能看到的唯一选择是测试 FooClass 的模拟而不是 FooClass 本身。然后,我会将 getUniqueConnection 函数替换为返回模拟/ stub 的函数。测试模拟似乎很糟糕,但我看不出有任何方法可以实现我所追求的目标。 UniqueConnection 是第三方供应商库,无法修改。

最佳答案

您可以创建一个 UniqueConnectionFactory,并将其实例传递给 FooClass。那么你有

  private function getUniqueConnection( $id ) {
    return $this->uniqueConnectionFactory->create( $id );
  }

一般来说,这是使用工厂的好处之一 - 您将 new 运算符保留在类之外,这使您可以更轻松地改变正在创建的对象。

关于php - 在单元测试中模拟被测试的对象是不是很糟糕?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11943473/

相关文章:

php - 我可以从 Laravel Blade 模板登录吗?

java - 在 Struts 2 中运行测试用例时出现错误

phpunit - PhpStorm 与 PHPUnit : PHP_CodeCoverage_Filter not found

来自 rest 端点的 PHP 模拟数据

php - 如何使用 PHPUnit 对异常进行单元测试?

php - Laravel 无法为用户模型创建策略

php - IE 中的语法错误? -ajax 和 Js

python - 从单元测试中的结果访问运行时

c# - 与数据库交互而不在数据库中创建数据的单元测试代码

php - 德鲁帕尔 7 : missing php code in default value