Php 预言-预期不会对对象调用任何方法

Php 预言-预期不会对对象调用任何方法,php,testing,mocking,phpunit,prophecy,Php,Testing,Mocking,Phpunit,Prophecy,现在,我在PHPUnit中使用以下代码,希望不会对模拟调用任何方法: $object = $this->createMock(ClassA:class); $object->expects($this->never())->method($this->anything()); 到目前为止,我还没有找到一种方法在预言中达到同样的结果。到目前为止,我只能测试特定方法的假设,而不能测试上面示例中的所有方法 目前,我正在使用以下自定义断言来测试是否没有调用任何方法。Pro

现在,我在PHPUnit中使用以下代码,希望不会对模拟调用任何方法:

$object = $this->createMock(ClassA:class);
$object->expects($this->never())->method($this->anything());
到目前为止,我还没有找到一种方法在预言中达到同样的结果。到目前为止,我只能测试特定方法的假设,而不能测试上面示例中的所有方法

目前,我正在使用以下自定义断言来测试是否没有调用任何方法。Prophecy的ObjectProphecy公开了一个方法来获取对特定函数的所有调用,所以我使用反射来获取类上的所有方法,而不是每个方法的每次调用。如果之后调用数组为空,我知道没有调用任何方法。该方法现在如下所示:

public function assertNoMethodHasBeenCalled(ObjectProphecy $prophecy, string $className)
{
    $methods = get_class_methods($className);

    $calls = [];
    foreach ($methods as $method) {
        $reflectionMethod = new \ReflectionMethod($className, $method);
        $numArgs = count($reflectionMethod->getParameters());
        $calls = array_merge(
            $calls,
            $prophecy->findProphecyMethodCalls(
                $method,
                new ArgumentsWildcard(array_fill(0, $numArgs, Argument::any()))
            )
        );
    }

    $this->assertEmpty($calls);
}

到目前为止,它对我有限的样本量有效,但我不满意。我觉得应该有一种更简单的方法来达到同样的效果。

据我所知,用预言来实现这一点并不简单

当涉及到预期时,预言的作用不同于PHPUnit的嘲笑。一旦你设定了一个期望,对你的模拟的每一个调用,如果不是一个预测或承诺,都会通过测试。鉴于以下对象预言:

$prophecy = $this->prophesize(ClassA::class);
$prophecy->methodA()->shouldNotBeCalled();

$objectA = $prophecy->reveal();
两者

考试会不及格


因此,当您没有设置任何期望值时,您必须像以前一样手动检查呼叫。

您能解释一下为什么必须检查此项吗?也许一个小例子会有所帮助。@PhilipWeinke我有一个更新对象的函数,我试图确保当满足某个条件时,对象不会被触碰(=>没有执行任何设置器)。因为你谈到设置器,它听起来像是某种数据对象。您可以只传入真实对象而不是模拟对象,并断言它没有更改。非常好的解决方案,谢谢!不知道用PHPUnit进行对象比较这么简单。基于一些快速测试和谷歌的assertEquals似乎做得很好。比我的呼叫检查器更简单(可能)更可靠的解决方案。其他人也更容易理解;)很高兴我能帮忙:)谢谢你的例子和说明!我想我还是保持原样吧,因为到目前为止,我只有几个案例需要这样做。我可能会为断言方法添加一些测试,以确保它确实如预期的那样工作。
$objectA->methodA();
$objectA->methodB();