PHP / Laravel: Почему отзывают эту функцию?

Я хотел бы понять, почему эта функция вызывается дважды в laravel, у меня этот Factory определен:

<?php

use Faker\Generator as Faker;

function my_callback (Faker $faker) { // <= LINE 5 
    return [
        // some key-value pairs, don't focus on that
        'id_ubicacion' => 1,
        'nombre' => $faker->name,
        'clase' => 'CONTROL ADMINISTRATIVO',
        'codigo' => $faker->ean13,
        // some other key-value pairs
    ];
} // <= LINE 29

$factory->define(App\Bien::class, 'my_callback');

тогда у меня есть следующие тесты:

<?php

namespace Tests\Unit;

use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;

use Faker\Factory as Faker;

class BienTest extends TestCase
{
    use RefreshDatabase;

    public function test__actualizar()
    {
        // setup
        $registro_a_actualizar = factory('App\Bien')->create(['id' => 1]);

        // more code...

    }

    public function test__destruir()
    {
        // setup
        $registro_a_destruir = factory('App\Bien')->create(['id' => 1]);

        // some code...
    }

когда я выполняю phpunit я получаю следующую ошибку

Fatal error: Cannot redeclare my_callback() 

(previously declared in \inven\database\factories\FactoryBien.php:5) 

in \inven\database\factories\FactoryBien.php on line 29

спасибо, если вы можете мне объяснить: почему функция my_callback() вызывается более одного раза?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
0
186
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Во-первых, мы должны понять, как работает средство запуска тестов.

Хотя каждый тест запускается в случайном порядке, на самом деле это не так. Кроме того, вы должны понимать, что setUp и tearDown запускаются всегда до и после каждого теста.

В методе setUp в Laravel он обновит приложение, если оно не запущено:

if (! $this->app) {
    $this->refreshApplication();
}

Итак, мы можем подумать: «Эй, мы поддерживаем работающим один экземпляр приложения, так что нам не нужно снова требовать ModelFactory, верно?»

НЕПРАВИЛЬНЫЙ.

В методе tearDown, который вызывается после каждого теста, он фактически уничтожает приложение прямо перед концом метода:

if ($this->app) {
    foreach ($this->beforeApplicationDestroyedCallbacks as $callback) {
        call_user_func($callback);
    }

    $this->app->flush();
    $this->app = null;
}

Это означает, что ваш файл ModelFactory включается каждый раз при запуске теста. Но это происходит в том же процессе PHP. Вот почему вы получаете ошибку уже определенной функции.

Чтобы доказать, что это легко, просто напишите это в своем файле ModelFactory:

global $a;
if (is_null($a)) {
    $a = 0;
}
else {
    $a++;
}
var_dump($a);

Вы увидите, что $a увеличивается при каждом запуске теста.

Чтобы решить вашу проблему, вы должны просто использовать анонимные функции следующим образом:

$factory->define(App\Bien::class, function (Faker $faker) {
    return [
        // some key-value pairs, don't focus on that
        'id_ubicacion' => 1,
        'nombre' => $faker->name,
        'clase' => 'CONTROL ADMINISTRATIVO',
        'codigo' => $faker->ean13,
        // some other key-value pairs
    ];
});

Я не должен объявлять какие-либо функции в фабричных файлах, не так ли?

byron perez 15.11.2018 21:57

Нет, не надо!

Steve Chamaillard 15.11.2018 22:15

Другие вопросы по теме