Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Codeception\Util\Stub methods ::exactly and ::once don't work

I am using Codeception\Util\Stub to create unit tests. And I want to be sure that my method called several times. For this I am using method 'exactly'.

Example:

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();
    }
}

As you can see I called myMethod once. But test passed. The same problem with method ::once , because this method is using the same class PHPUnit_Framework_MockObject_Matcher_InvokedCount ('matcher' below). Test will fail only if I will call more then expected times ( >2 ). Because matcher's method 'invoked' checks if count more then expected. But can't see if someone call matcher's method 'verify' to check if myMethod called less then expected.

Sorry stackoverflow, this is my first question.

UPDATE

My fast and BAD temporary solution:

Add stub into helper

$I->addStubToVerify($stub);

Add method into helper to validate:

protected $stubsToVerify = [];
public function verifyStubs()
{
    foreach ($this->stubsToVerify as $stub) {
        $stub->__phpunit_getInvocationMocker()->verify();
    }
    return $this;
}

Call this method in Cest's method _after():

public function _after(UnitTester $I)
{
    $I->verifyStubs();
}
like image 366
vatvit Avatar asked Oct 01 '14 11:10

vatvit


2 Answers

Instead of use \Codeception\Util\Stub to Expected::once(), modify your unit tests to extends \Codeception\Test\Unit then use $this->make() or $this->makeEmpty() to create your stubs. It will works as you expect ;)

For example:

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);
    }
}

Cheers!

like image 132
Chemaclass Avatar answered Nov 13 '22 10:11

Chemaclass


You need to pass $this as a third parameter to makeEmpty:

$stub = StubUtil::makeEmpty('myClass', [
    'myMethod' => StubUtil::exactly(2, function () { return 'returnValue'; })
], $this);
like image 29
Valentin Rodygin Avatar answered Nov 13 '22 10:11

Valentin Rodygin