被测类的假方法

Posted

技术标签:

【中文标题】被测类的假方法【英文标题】:Fake method of class under test 【发布时间】:2021-05-26 18:16:18 【问题描述】:

例如我有一堂课

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() 中调用的api 获得另一个响应

public function testFunctionToTest()

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

  $classUnderTest = new Foo('settingUsedInloadSettings');

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

我该怎么做?

【问题讨论】:

在这种特殊情况下,我从生产目录加载loadSettings() 中的文件,但对于第二次测试,我想从我的固定装置目录加载“假文件”。 【参考方案1】:

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

public function testFunctionToTest()

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

    // ...

【讨论】:

以上是关于被测类的假方法的主要内容,如果未能解决你的问题,请参考以下文章

python中suite.addTest没有执行测试用例,求大神指教,附件分别是main文件与被测类login与logout。

如何通过反射访问一个类的私有方法

如何通过反射访问一个类的私有方法

更新gradle后Android单元测试无法解析被测类

如何修补与被测类在同一文件中的类,即在测试开始之前初始化?

如何注入不提供接口和虚拟方法的类的假实现?