Php Codeception\Util\Stub方法::精确和::once don';行不通

Php Codeception\Util\Stub方法::精确和::once don';行不通,php,unit-testing,stub,codeception,Php,Unit Testing,Stub,Codeception,我正在使用Codeception\Util\Stub创建单元测试。我想确定我的方法调用了几次。为此,我使用的是“精确”方法 例如: use \UnitTester; use \Codeception\Util\Stub as StubUtil; class someCest { public function testMyTest(UnitTester $I) { $stub = StubUtil::makeEmpty('myClass', [

我正在使用Codeception\Util\Stub创建单元测试。我想确定我的方法调用了几次。为此,我使用的是“精确”方法

例如:

use \UnitTester;
use \Codeception\Util\Stub as StubUtil;

class someCest
{
    public function testMyTest(UnitTester $I)
    {
        $stub = StubUtil::makeEmpty('myClass', [
            'myMethod' => StubUtil::exactly(2, function () { return 'returnValue'; })
        ]);
        $stub->myMethod();
    }
}
正如您所看到的,我曾经调用过myMethod。但测试通过了。 method::once也存在同样的问题,因为该方法使用的是同一类PHPUnit\u Framework\u MockObject\u Matcher\u InvokedCount(下面的“Matcher”)。 只有在调用次数超过预期次数(>2)时,测试才会失败。因为matcher的方法“调用”检查计数是否超过预期值。但看不出是否有人调用matcher的方法“验证”,以检查myMethod的调用是否低于预期

对不起,这是我的第一个问题

更新

我的快速和糟糕的临时解决方案:

将存根添加到帮助器中

$I->addStubToVerify($stub);
将方法添加到帮助器以验证:

protected $stubsToVerify = [];
public function verifyStubs()
{
    foreach ($this->stubsToVerify as $stub) {
        $stub->__phpunit_getInvocationMocker()->verify();
    }
    return $this;
}
在Cest的方法_after()中调用此方法:


您需要将
$this
作为第三个参数传递给
makeEmpty

$stub = StubUtil::makeEmpty('myClass', [
    'myMethod' => StubUtil::exactly(2, function () { return 'returnValue'; })
], $this);

不要将
\Codeception\Util\Stub
用于
预期的::once()
,而是将单元测试修改为
扩展\Codeception\Test\unit
,然后使用
$this->make()
$this->makeEmpty()
创建存根。它将按照您的预期工作;)

例如:

class MyProcessorTest extends \Codeception\Test\Unit 
{
    public function testSomething()
    {
        $processor = new MyProcessor(
            $this->makeEmpty(EntityManagerInterface::class, [
                'remove' => Expected::never(),
                'persist' => Expected::once(),
                'flush' => Expected::once(),
            ])
        );

        $something = $this->somethingFactory(Processor::OPERATION_CREATE);
        $processor->process($something);
    }
}

干杯

看起来您的方法在模拟的目标类中不存在

如果该方法存在,那么Codeception将用您提供的存根替换它。如果此方法不存在,则Codeception会将具有此名称的字段添加到存根对象

这是因为方法和属性在同一数组中传递,所以Codeception没有其他方法来区分方法和属性


因此,首先在类myClass中创建一个方法myMethod。

您的解决方案不起作用。方法::make()和::makeEmpty()的第三个参数为PHPUnit_Framework_TestCase,但$this是someCest,不扩展PHPUnit_Framework_TestCase。
class MyProcessorTest extends \Codeception\Test\Unit 
{
    public function testSomething()
    {
        $processor = new MyProcessor(
            $this->makeEmpty(EntityManagerInterface::class, [
                'remove' => Expected::never(),
                'persist' => Expected::once(),
                'flush' => Expected::once(),
            ])
        );

        $something = $this->somethingFactory(Processor::OPERATION_CREATE);
        $processor->process($something);
    }
}