Сбой теста формы PHPUnit в DateTime - PullRequest
0 голосов
/ 20 сентября 2018

У меня несколько локальных тестов не пройдены на моем локальном компьютере, потому что значения DateTime отличаются:

4) Tests\AppBundle\Form\AssetStatusTypeTest::testValidForm with data set #0 (array('active'))
Failed asserting that two objects are equal.
--- Expected
+++ Actual
@@ @@
     'status' => 'active'
    'type' => null
    'amount' => null
-    'createdAt' => 2018-09-20T20:34:47.047520+0200
+    'createdAt' => 2018-09-20T20:34:47.047870+0200
     'updatedAt' => null
     'contract' => null
     'admin' => null

Тест:

public function testValidForm($data)
{
    $form = $this->factory->create(AssetStatusType::class);
    $object = Entity::fromArray(new Asset(), $data);
    $form->submit($data);
    $this->assertTrue($form->isSynchronized());
    $this->assertEquals($object, $form->getData());
    $view = $form->createView();
    $children = $view->children;
    foreach (array_keys($data) as $key) {
        $this->assertArrayHasKey($key, $children);
    }
}

Что более или менее скопировано издокументы .

Теперь поле createdAt установлено так:

public function __construct()
{
    if (empty($this->createdAt)) {
        $this->createdAt = new \DateTime();
    }
}

Моя главная мысль: этот тест проходит на нашем Jenkins.Это не локально на нескольких машинах разработчика.Моим первым побуждением было проверить настройки часового пояса ini.

Интересно, как это вообще возможно.Если я правильно понял, ожидается, когда object был создан, и фактическим, когда форма отправлена.Таким образом, оба объекта никогда не могут иметь одинаковую отметку времени createdAt.Если precision, вероятно, не очень низкий.

1 Ответ

0 голосов
/ 20 сентября 2018

На двух машинах работают разные версии PHP.PHP7.1 (и выше) включает микросекунды, когда он создает объект DateTime, но код, работающий на PHP 5.x и 7.0, не будет.

Есть два способа работы с этим:

  • Не сравнивайте точные даты и время, а конвертируйте их в секунды с $datetimeObj->format('U');.Вы по-прежнему будете получать случайные сбои теста, когда один тест создается, скажем, в 1.99998, а следующий вызов для создания даты и времени - в 2.0001, и поэтому тест по-прежнему не выполняется при преобразовании в секунды.
  • Использование 'Часы издеваются '.Используя некоторые интересные трюки с пространствами имен PHP, глобальная функция time() переопределяется (тоже sleep()).Вы должны создать новый объект DateTime, чтобы убедиться, что они действительно используют новую версию функции time (), но часы будут эффективно останавливаться - а sleep () просто превращается во что-то более похожее на $time += $seconds; - что также означает, чтоsleep(3600); занимает эффективное нулевое время.

Symfony / phpunit-bridge ClockMock.php можно использовать просто как библиотеку, если вы не хотите включать его в качестве слушателя в конфигурацию PHPunit.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...