正在测试class的假方法

Fake method of class under test

例如我有一个class

class Foo {

  protected $settingUsedInloadSettings;
  protected $settings;

  public function __construct($param) {
    $this->$settingUsedInloadSettings = $param;
    $this->loadSettings();
    //do other initial stuff
  }

  protected function loadSettings() {
    $this->settings['settingToFake'] = 'some data using' 
      . $this->$settingUsedInloadSettings
      . 'and stuff from database and/or filesystem';
  }

  public function functionUnderTest() {
    //do api-calls with $this->settings['settingToFake']
  }

}

$this->settings['settingToFake']

中有效数据的工作测试
class FooTest extends TestCase {

  public function testFunctionToTest(){

    $classUnderTest = new Foo('settingUsedInloadSettings');

    $actual = $classUnderTest->functionUnderTest();
    $expected = ['expectedValue'];
    $this->assertEquals($expected, $actual);
  }

}

现在我希望 loadSettings() 在第二次测试中将无效数据设置为 $this->settings['settingToFake'],以便从 functionUnderTest()[=18= 中调用的 api 获得另一个响应]

public function testFunctionToTest(){

  //fake / mock / stub loadSettings() some how

  $classUnderTest = new Foo('settingUsedInloadSettings');

  $actual = $classUnderTest->functionUnderTest();
  $expected = ['expectedValue'];
  $this->assertEquals($expected, $actual);
}

我该怎么做?

您可以通过在测试中覆盖匿名 class 中的 loadSettings 方法来实现:

public function testFunctionToTest()
{
    $classUnderTest = new class('settingUsedInloadSettings') extends Foo {
        protected function loadSettings()
        {
           $this->settings['settingToFake'] = 'invalid value';
        }
    };

    // ...
}