如果数组是在 setUp 方法中初始化的,则在测试函数的 Symfony TestCase 类中向数组添加值

Add value to array in Symfony TestCase class in test function if the array was initialised in setUp method

提问人:user_51 提问时间:9/12/2023 更新时间:9/16/2023 访问量:67

问:

如果问题看起来不对劲,我很抱歉,我是 Stack Overflow 和 php 的新手。

我的班级看起来有点像这样:

final class MyClass extends TestCase
{
  private MyService $myService;
  private ObjectProphecy $object;
  private array $x;

  protected function setUp(): void
  {
    $this->object = $this->getProphet()->prophesize(MyOtherClass::class);

    $this->x = [];
    $this->object->foo()->willReturn($this->x);
  }

  public function test(): void
  {
    $this->x = [1];
    $this->myService->bar();
  }
}

问题是,在 的调用中,在执行 时,我得到 ,这是在方法中设置的,我希望它是相反的。$this->myService->bar();object->foo()[]setUp()[1]

我怀疑这是因为复制了副本,然后没有注意到我后来所做的更改。但是,如果我更改为某个对象而不是数组,则一切都会像我期望的那样工作。$this->object->foo()->willReturn($this->x);$this->x$x

处理这个问题的最干净的方法是什么?我希望像声明为指向数组的指针这样的东西,但这似乎是不可能的?$x

PHP 数组 symfony 传递引用 预言

评论

0赞 Markus Zeller 9/12/2023
使用代替速记。这将在通话时进行评估。will($this->returnValue($this->x))
0赞 user_51 9/13/2023
有趣的是,如果我尝试您的建议,我会得到一些类型不匹配错误。然而,根据这个 stackoverflow.com/questions/33868479/... - 两者的行为应该完全相同。因此,如果我没看错的话,你的建议也不应该起作用,我也不应该看到我所看到的行为,所以很明显,我至少做错了什么。
0赞 Markus Zeller 9/13/2023
根据参考资料:<-- .尝试在此处使用 getter 而不是直接值。Using the will($this->returnValue()) method, for instance, you can configure these dummy implementations to return a value when called.when called
1赞 user_51 9/15/2023
看起来问题是我正在使用 ,而您的示例正在使用 .我怀疑这就是为什么完全更改为您最初建议的失败的原因,也是为什么完全更改为对我来说失败的原因。这些不存在。如果我想要实现的目标可行,我会进一步挖掘,但 github.com/phpspec/prophecy/issues/225 建议它可能不是。你知道这是否可行吗?ObjectProphecyMockObjectwill($this->returnValue($this->x))willReturnReferenceObjectProphecyObjectProphecyObjectProphecy
1赞 user_51 9/16/2023
没关系,谢谢你的努力!这绝对是非常有用的。也许你可以在答案的开头加上这样的话:“根据link_i_posted这是不可能的,但你可以按如下方式做到这一点......”?如果是这样,我很乐意将其标记为正确。井。。也就是说,如果您足够信任我提供的链接,这是不可能的:-)ObjectProphecyMockObject

答:

0赞 Markus Zeller 9/13/2023 #1

可以返回引用。已针对 PHPUnit 10.3 进行测试。

注意

这没有经过测试,似乎没有实现默认的模拟对象。因此,对于此示例代码,我改用了原生 PHPUnit。ObjectProphecyMockObject

<?php declare(strict_types=1);

use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;

// Never used, but neccessary to have a class to be able to create a mock
class MyFoo {
    public function foo(): array
    {
        var_dump('called foo()');

        return ['foo'];
    }
}

final class ReturnTest extends TestCase
{
    private MockObject $mock;
    private array      $x;

    protected function setUp(): void
    {
        $this->x = [];
        $this->mock = $this->createMock(MyFoo::class);
        $this->mock->method('foo')->willReturnReference($this->x);
    }

    public function test(): void
    {
        $this->assertEquals([], $this->mock->foo());
        $this->x = [1];
        $this->assertEquals([1], $this->mock->foo());
    }
}