如何模拟对象属性?

时间:2014-07-26 06:07:11

标签: php unit-testing symfony mocking phpunit

我试图模仿属性,但无法让它发挥作用。在这种情况下,我试图模拟请求属性Symfony\Component\HttpFoundation\Request

根据this回答,我应该返回__get

的值

以下代码一直显示NULL

$testRequest = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')
  ->disableOriginalConstructor()
  ->getMock();
$testRequest->expects($this->any())
  ->method('__get')
  ->with($this->equalTo('request'))
  ->will($this->returnValue("working"));
var_dump($testRequest->request);

也许是因为答案太旧了,所以查看current documentation嘲讽,但是根本没有提到如何模拟属性。

根据另一个答案,我可以尝试以下方法:

private $post=array('search'=>'abc','start'=>null);
...
$paramBag = $this->getMockBuilder('Symfony\Component\HttpFoundation\ParameterBag')
  ->disableOriginalConstructor()
  ->getMock();
foreach($this->post as $key=>$value){
  echo "setting:".$key.' with:'.$value.PHP_EOL;              
  $paramBag->expects($this->any())
    ->method('get')
    ->with($this->equalTo($key))
    ->will($this->returnValue($value));
}
$this->request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')
  ->disableOriginalConstructor()
  ->getMock();
$this->request->request=$paramBag;
echo ($this->request->request->get('start'));

这让我:

Expectation failed for method name is equal to <string:get> when invoked zero or more times
Parameter 0 for invocation Symfony\Component\HttpFoundation\ParameterBag::get('search', null, false) does not match expected value.
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'search'
+'start'

是否无法使用不同的值覆盖多个方法?同样,文档完全没有任何示例。

如果我尝试echo ($this->request->request->get('start'));,它会因为期待搜索而失败,但会开始。我无法给它一些不会失败的东西。

尝试单元测试,但Symfony2似乎没有这样的东西。每个documentation几乎立即跳过单元测试,其中包含不需要依赖的普通类的示例,然后转向功能测试。一些文件说明unit testing for repositories is not recommended

我想看看是否正确创建了DQL语句,并且没有记录选项进行单元测试。

可以通过创建假Doctrine\ORM\EntityRepository类来完成此部分,并在测试开始时包含该文件。与Symfony\Component\HttpFoundation\Request尝试相同,但在尝试执行此操作时获得can't re define this class。以某种方式加载我的测试Symfony\Component\HttpFoundation\Request已加载。

1 个答案:

答案 0 :(得分:1)

不完全确定你是如何表示模拟属性的,我会假设属性是通过getter和setter设置的,然后你可以用你想要的任何模拟来设置它们。

但是,如果您需要将模拟对象分配给您没有访问器方法的私有/受保护属性,则可以执行以下操作:

$reflection = new \ReflectionClass($objectThatContainsThePropertyToMock);
$property   = $reflection->getProperty($propertyName);
$property->setAccessible(true);
return $property->setValue($mockedObject);