Издевательство над объектом PDO с помощью PHPUnit


Мне трудно издеваться над объектом PDO с помощью PHPUnit.

Похоже, в Интернете не так много информации о моей проблеме, но из того, что я могу собрать:

  1. PDO имеет "окончательные" методы __пробуждения и __сна, которые предотвращают его сериализацию.
  2. Реализация фиктивного объекта PHPUnit сериализует объект в какой-то момент.
  3. Модульные тесты затем завершаются ошибкой PHP, сгенерированной PDO, когда это происходит.

Имеется в виду функция чтобы предотвратить такое поведение, добавьте следующую строку в модульный тест:

class MyTest extends PHPUnit_Framework_TestCase

{    
    protected $backupGlobals = FALSE;
     // ...

}

Источник: http://sebastian-bergmann.de/archives/797-Global-Variables-and-PHPUnit.html

Это не работает для меня, мой тест все еще выдает ошибку.

Полный тестовый код:

class MyTest extends PHPUnit_Framework_TestCase
{

    /**
     * @var MyTest
     */
    private $MyTestr;

    protected $backupGlobals = FALSE;

    /**
     * Prepares the environment before running a test.
     */
    protected function setUp()
    {
        parent::setUp();

    }

    /**
     * Cleans up the environment after running a test.
     */
    protected function tearDown()
    {

        parent::tearDown();
    }

    public function __construct()
    {

        $this->backupGlobals = false;
        parent::__construct();

    }


    /**
     * Tests MyTest->__construct()
     */
    public function test__construct()
    {

        $pdoMock = $this->getMock('PDO', array('prepare'), array(), '', false);

        $classToTest = new MyTest($pdoMock);

        // Assert stuff here!


    }

    // More test code.......

Кто-нибудь из профессионалов PHPUnit поможет мне?

Спасибо,

Бен

Author: Galen, 2010-06-29

3 answers

$BACKUPGLOBALS вам не поможет, потому что эта ошибка исходит из другого источника. PHPUnit 3.5.2 (возможно, и более ранние версии) содержит следующий код в PHPUnit/Framework/MockObject/Generator.php

    if ($callOriginalConstructor &&
        !interface_exists($originalClassName, $callAutoload)) {
        if (count($arguments) == 0) {
            $mockObject = new $mock['mockClassName'];
        } else {
            $mockClass  = new ReflectionClass($mock['mockClassName']);
            $mockObject = $mockClass->newInstanceArgs($arguments);
        }
    } else {
        // Use a trick to create a new object of a class
        // without invoking its constructor.
        $mockObject = unserialize(
          sprintf(
            'O:%d:"%s":0:{}',
            strlen($mock['mockClassName']), $mock['mockClassName']
          )
        );
    }

Этот "трюк" с несериализацией используется, когда вы просите getmock не выполнять исходный конструктор, и он быстро завершится неудачей с PDO.

Итак, как же обойти это?

Одним из вариантов является создание помощника по тестированию, подобного этому

class mockPDO extends PDO
{
    public function __construct ()
    {}

}

Цель здесь состоит в том, чтобы получить избавьтесь от оригинального конструктора PDO, который вам не нужен. Затем измените свой тестовый код на следующий:

$pdoMock = $this->getMock('mockPDO', array('prepare'));

Создание макета, подобного этому, приведет к выполнению оригинального конструктора, но поскольку теперь он безвреден благодаря помощнику по тестированию mockPDO, вы можете продолжить тестирование.

 47
Author: Anti Veeranna, 2010-11-02 22:23:36

Лучшее, что я могу придумать, это использовать runkit и переопределить два последних метода как защищенные с помощью runkit_function_redefine.

Не включайте параметр runkit.internal_override в php.ini.

для get, чтобы включить параметр runkit.internal_override в php.ini.

И, как всегда, как и в случае с eval, если runkit кажется ответом, вопрос, вероятно, неверен:)

 2
Author: omarshariffdontlikeit, 2010-06-29 09:43:15

Вы создаете экземпляр своего тестового случая в своем тестовом случае?

$classToTest = new MyTest($pdoMock);

Прямо сейчас вы, по сути, тестируете свой тестовый случай. Это должно быть что-то вроде:

$classToTest = new My($pdoMock);
 1
Author: netcoder, 2013-09-18 05:42:35