PHPUnit 用存根覆盖实际方法

PHPUnit overwrite actual method with stub

我刚开始使用 PHPUnit,我想知道是否可以 overwrite/replace 一个带有存根的方法。我有一些使用 Sinon 的经验,使用 Sinon 这是可能的 (http://sinonjs.org/docs/#stubs)

我想要这样的东西:

<?php

class Foo {

  public $bar;

  function __construct() {
    $this->bar = new Bar();
  }

  public function getBarString() {
    return $this->bar->getString();
  }

}

class Bar {

  public function getString() {
    return 'Some string';
  }

}



class FooTest extends PHPUnit_Framework_TestCase {

  public function testStringThing() {
    $foo = new Foo();

    $mock = $this->getMockBuilder( 'Bar' )
      ->setMethods(array( 'getString' ))
      ->getMock();

    $mock->method('getString')
      ->willReturn('Some other string');

    $this->assertEquals( 'Some other string', $foo->getBarString() );
  }

}

?>

这行不通,您将无法在 Foo 实例中模拟 Bar 实例。 Bar 在 Foo 的构造函数中实例化。

更好的方法是将 Foo 的依赖项注入 Bar,即。即:

<?php

class Foo {

  public $bar;

  function __construct(Bar $bar) {
    $this->bar = $bar;
  }

  public function getBarString() {
    return $this->bar->getString();
  }
}

class Bar {

  public function getString() {
    return 'Some string';
  }

}

class FooTest extends PHPUnit_Framework_TestCase {

  public function testStringThing() {

    $mock = $this->getMockBuilder( 'Bar' )
      ->setMethods(array( 'getString' ))
      ->getMock();

    $mock->method('getString')
      ->willReturn('Some other string');

    $foo = new Foo($mock); // Inject the mocked Bar instance to Foo

    $this->assertEquals( 'Some other string', $foo->getBarString() );
  }
}

有关 DI 的小教程,请参阅 http://code.tutsplus.com/tutorials/dependency-injection-in-php--net-28146