Методы Codeception\Util\Stub ::exactly и ::once не работают

Я использую 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. Но испытание пройдено. Та же проблема с методом ::once , потому что этот метод использует тот же класс PHPUnit_Framework_MockObject_Matcher_InvokedCount («сопоставитель» ниже). Тест завершится неудачей, только если я буду звонить больше, чем ожидалось ( > 2 ). Потому что «вызванный» метод сопоставления проверяет, превышает ли ожидаемое количество. Но не вижу, вызывает ли кто-нибудь метод сопоставления «проверить», чтобы проверить, вызывается ли myMethod меньше, чем ожидалось.

Извините, stackoverflow, это мой первый вопрос.

ОБНОВЛЕНИЕ

Мое быстрое и ПЛОХОЕ временное решение:

Добавить заглушку в помощник

$I->addStubToVerify($stub);

Добавьте метод в помощник для проверки:

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

Вызовите этот метод в методе Cest _after():

public function _after(UnitTester $I)
{
    $I->verifyStubs();
}

person vatvit    schedule 01.10.2014    source источник


Ответы (3)


Вам нужно передать $this в качестве третьего параметра в makeEmpty:

$stub = StubUtil::makeEmpty('myClass', [
    'myMethod' => StubUtil::exactly(2, function () { return 'returnValue'; })
], $this);
person Valentin Rodygin    schedule 05.11.2014
comment
Ваше решение не работает. метод ::make() и ::makeEmpty() имеют третий параметр как PHPUnit_Framework_TestCase, но $this является someCest и не расширяет PHPUnit_Framework_TestCase. - person vatvit; 10.11.2014

Вместо использования \Codeception\Util\Stub в Expected::once() измените модульные тесты на extends \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);
    }
}

Ваше здоровье!

person Chemaclass    schedule 11.04.2019

Похоже, ваш метод не существует в целевом классе, над которым вы издеваетесь.

Если метод существует, Codeception заменяет его предоставленной вами заглушкой. А если этого метода нет, то Codeception добавляет в объект-заглушку поле с таким названием.

Это связано с тем, что методы и свойства передаются в одном и том же массиве, поэтому у Codeception нет другого способа отличить методы от свойств.

Итак, сначала создайте метод myMethod в вашем классе myClass.

person Alexey Inkin    schedule 31.10.2019