PHPUnit:如何测试一个方法是否有';我不曾被称为;然而",;,但稍后在测试用例中会调用吗?

PHPUnit:如何测试一个方法是否有';我不曾被称为;然而",;,但稍后在测试用例中会调用吗?,php,unit-testing,phpunit,Php,Unit Testing,Phpunit,我需要测试一个方法在测试用例中的某个点上没有被调用,但是预期稍后会被调用。下面是一个示例测试: <?php class B { public function doSomething() {} } class A { private $b; private $buffer = array(); public function __construct($b) { $this->b = $b; } public fu

我需要测试一个方法在测试用例中的某个点上没有被调用,但是预期稍后会被调用。下面是一个示例测试:

<?php

class B {
    public function doSomething() {}
}

class A {
    private $b;
    private $buffer = array();

    public function __construct($b) {
        $this->b = $b;
    }

    public function x($val) {
        $this->buffer[] = $val;

        if (count($this->buffer) == 3) {
            $this->b->doSomething();
        }
    }
}

class XTest extends PHPUnit_Framework_TestCase {
    public function testB() {
        $b = $this->getMock('B');
        $a = new A($b);

        $a->x(1);
        $a->x(2);

        // doSomething is not called YET
        $b->expects($this->never())->method('doSomething');

//      $b->expects($this->at(0))->method('doSomething'); // ??????

        $a->x(3);
    }
}

在你的情况下,我认为没有必要这样做。另外,我也没有办法检查以前的电话。我宁愿检查参数
flush()
是否与以下参数一起执行:

$b = $this->getMock('B');
$b->expects($this->exactly(1))
    ->method('flush')
    ->with(array(1, 2, 3));

$a = new A($b);

$a->x(1);
$a->x(2);
$a->x(3);

通常,如果调用了其他模拟方法,您需要检查以前的方法,这可以通过告诉模拟方法它们应该在何时使用
at()
调用来完成

似乎是另一种测试用例方法OK,因此,如果,例如,
flush
不是用缓冲区的内容调用的,而是用不同的东西调用的,例如“一旦缓冲区有3个项目,ping外部服务”,我如何测试该服务直到正好有3个项目才ping?我不确定我是否完全理解您的意思。您使用
flush
ping外部服务,对吗?在本例中,您已经对其进行了测试。当与此精确数组不同的内容被用作参数0或多次调用该方法时,PHPUnit将立即抛出错误。这是测试一个触发器如何触发
flush
的最严格的方法,我在原始问题中编辑了代码来说明。对于更新后的代码,如何使用PHPUnit确保在数组中有3个项而不是2个或4个项时调用
doSomething
?只需尝试此硬编码以查看模拟的行为。如果数组中有2个或4个项目,我发布的测试将失败,因为
doSomething
只有在
array(1,2,3)
作为参数0传递时才会起作用-此数组正好有三个条目。因此,更新的代码无法工作,因为您没有将缓冲区传递给
doSomething
。在这种情况下,您需要为缓冲区定义一个getter,在执行后获取缓冲区,并根据预期结果断言它。也许这会帮助你理解嘲弄: