与此
相关我正在尝试这个测试代码
<?php
use Monolog\Test\TestCase;
use Prophecy\Prophecy\ObjectProphecy;
use Prophecy\Prophet;
class MyBar {
public int $bar = 0;
}
class MyFoo {
public function fooArray(): array {
return [];
}
public function fooBar(): MyBar {
return new MyBar();
}
public function fooInt(): int {
return 0;
}
}
final class SimpleTest extends TestCase
{
private Prophet $prophet;
private ObjectProphecy $mock;
private array $myArray;
private MyBar $myBar;
private int $myInt;
public function getProphet(): Prophet {
return $this->prophet;
}
protected function setUp(): void {
$this->prophet = new Prophet();
$this->myArray = [0];
$this->myBar = new MyBar();
$this->myInt = 0;
$this->mock = $this->getProphet()->prophesize(MyFoo::class);
$this->mock->fooArray()->willReturn($this->myArray);
$this->mock->fooBar()->willReturn($this->myBar);
$this->mock->fooInt()->willReturn($this->myInt);
}
public function test(): void {
$this->myArray = [1];
$this->assertEquals([0], $this->mock->reveal()->fooArray());
$this->myBar->bar = 1;
$this->assertEquals(1, $this->mock->reveal()->fooBar()->bar);
$this->myInt = 1;
$this->assertEquals(0, $this->mock->reveal()->fooInt());
}
}
请注意测试函数中的差异,数组
$myArray
不会更新,int $myInt
也不会更新,但对象 $myBar
会更新。
我正在考虑将数组作为参考传递,但根据this,
ObjectProphecy
可能无法实现。我在顶部链接的问题的答案建议使用另一种方法 MockObject
来解决,但我试图看看 ObjectProphecy
中是否有解决方案。
您正在测试完全不同的东西(比较番茄和土豆)。希望我在下面已经很好地解释了这种情况。
回答你的第一个问题,我以
$this->myInt
为例(不过,这也涉及到$this->myArray
);
在您的
setup()
函数中,您使用三个步骤:
您的第一步是将
0
分配给 $this->myInt
:
$this->myInt = 0;
你的第二步是创建一个对象:
$this->mock = $this->getProphet()->prophesize(MyFoo::class);
你的第三步(#3)是为对象分配值
0
(来自$this->myInt
):$this->mock->fooInt()->willReturn($this->myInt);
然后在你的实际测试函数中(
test()
):
作为第四步 (#4),您将
$this->myInt
值更改为 1
:
$this->myInt = 1;
作为第五步(#5),您实际上正在测试
object
的值,根据 step #3
仍应返回 0
:
$this->assertEquals(0, $this->mock->reveal()->fooInt());
在最后一步中,您实际上是将
0
与您在 step #3
中设置的值(根据 $this->myInt = 0
为 step #1
)进行比较。例如。您的测试将通过。 Step #4
没有做任何事情,因为您没有更改对象的值(您正在测试),您只是更改 class
中的私有参数的值。仅当您测试 $this->myInt
的值时,您的预期行为才有效,如下所示:
$this->assertEquals(0, $this->myInt);
因此,要解决您的问题,请重写您的测试或确保您更改正确的值(在您的
class
内或在 object
内)。
为了解释您的
object
示例以及为什么有所不同,您实际上是在更改 object
中的值并在测试中测试相同的 value
(正确测试):
$this->myBar->bar = 1;
$this->assertEquals(1, $this->mock->reveal()->fooBar()->bar);
您更改了
value
中的 object
。再一次,您的测试将通过。
要回答你的第二个问题,请将
step #4
更改为:
$this->myInt = 1;
$this->mock->fooInt()->willReturn($this->myInt);
// and then to do your test from step #5:
$this->assertEquals(0, $this->mock->reveal()->fooInt());
// this should fail.