PHPUnit-创建模拟对象作为属性的存根

PHPUnit-创建模拟对象作为属性的存根,php,mocking,phpunit,Php,Mocking,Phpunit,我试图在PHPunit中配置一个Mock对象,以返回不同属性的值(使用_get函数访问这些属性) 例如: class OriginalObject { public function __get($name){ switch($name) case "ParameterA": return "ValueA"; case "ParameterB": return "ValueB"; } } 我试图用以下方式来模拟这一点: $mockObject = $this->getMo

我试图在PHPunit中配置一个Mock对象,以返回不同属性的值(使用_get函数访问这些属性)

例如:

class OriginalObject {
 public function __get($name){
switch($name)
 case "ParameterA":
  return "ValueA";
 case "ParameterB":
  return "ValueB";
 }
}
我试图用以下方式来模拟这一点:

$mockObject = $this->getMock("OrigionalObject");

$mockObject    ->expects($this->once())
    ->method('__get')
    ->with($this->equalTo('ParameterA'))
    ->will($this->returnValue("ValueA"));

$mockObject    ->expects($this->once())
    ->method('__get')
    ->with($this->equalTo('ParameterB'))
    ->will($this->returnValue("ValueB"));

但这失败得可怕:-(

我还没有试过嘲弄,但也许这会奏效:

// getMock() is deprecated
// $mockObject = $this->getMock("OrigionalObject");
$mockObject = $this->createMock("OrigionalObject");

$mockObject->expects($this->at(0))
    ->method('__get')
    ->with($this->equalTo('ParameterA'))
    ->will($this->returnValue('ValueA'));

$mockObject->expects($this->at(1))
    ->method('__get')
    ->with($this->equalTo('ParameterB'))
    ->will($this->returnValue('ValueB'));
我已经在测试中使用了$this->at(),它可以工作(但不是最佳解决方案)

这应该可以:

class Test extends \PHPUnit_Framework_TestCase {
...
    function testSomething() {
         $mockObject = $this->getMock("OrigionalObject");

         $mockObject
              ->expects( $this->any() )
              ->method('__get')
              ->will( $this->returnCallback('myMockGetter'));
         ...
     }
...
}

function myMockGetter( $classPropertyName ) {
    switch( $classPropertyName ) {
        case 'ParameterA':
            return 'ValueA';

        case 'ParameterB':
            return 'ValueB';
    }
}
... ... 

模拟代码中的输入错误(“Original”而不是“Original”,缺少ValueA和ValueB的结束引号)是您实际代码的一部分,还是转录错误?哈哈,谢谢Phil(指出我的阅读障碍)输入错误(现在修改)只是在示例代码中-显然这不是实际执行的代码Hey koen$this->at()对我有用-谢谢;-)为什么你不认为这是一个最佳的解决方案?它不是真正的可伸缩性,而且测试很难阅读。如果给回调起个好名字,它可能更容易阅读。但首先,我要看的是如何重构_get。此外,您正在测试状态(有人认为这是一种糟糕的做法),甚至是私有状态(许多人认为这是一种糟糕的做法)。当然,有些聪明的人并不认为这有什么问题,你也可能是他们中的一员。我认为我的解决方案比koen更为理想,但他在评论中提出了一些重要的观点。我认为一个可能的解决方案是创建一个测试类,而不是使用模拟对象。这通常用于HTTP适配器之类的东西。