Фабрика считает 2 модели вместо 1 в тестах - PullRequest
0 голосов
/ 09 января 2020

У меня есть следующие миграции:

class CreateOrdersTable extends Migration
{
    public function up()
    {
        Schema::create('orders', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->unsignedBigInteger('user_id');
            $table->timestamps();

            $table->foreign('user_id')->references('id')->on('users');
        });
    }
}
class CreatePaymentsTable extends Migration
{
    public function up()
    {
        Schema::create('payments', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->unsignedBigInteger('order_id');
            $table->timestamps();

            $table->foreign('order_id')->references('id')->on('orders');
        });
    }
}

и эти фабрики:

$factory->define(Payment::class, function (Faker $faker) {
    return [
        'order_id' => factory(Order::class)->create(),
    ];
});
$factory->define(Order::class, function (Faker $faker) {
    return [
        'user_id' => factory(User::class)->create(),
    ];
});

Теперь в моем тесте у меня есть это:

/** @test */
public function it_should_count_1_order()
{
     $order = factory(Order::class)->create();

     $payment = factory(Payment::class)->create([
         'order_id' => $order->id,
     ]);

     $this->assertEquals(1, Order::count())
}

Счет таблицы заказов дает мне 2. Почему? это должно быть 1, поскольку я говорю фабрике платежей переопределить order_id с данным заказом. Я что-то упустил?

Ответы [ 2 ]

1 голос
/ 09 января 2020

Поскольку ваш Payment factory создает Order, вам не нужно создавать Order перед этим и передавать его Payment factory.

/** @test */
public function it_should_count_1_order()
{
     $payment = factory(Payment::class)->create();

     $this->assertEquals(1, Order::count())
}
0 голосов
/ 09 января 2020

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

$factory->define(Order::class, function (Faker $faker) {
    return [
        'user_id' => factory(User::class),
});

Если это не помогает, убедитесь, что вы используете в своих тестах DatabaseTransactions или DatabseMigrations тест и очистите базу данных перед запуском теста 1-го время. В противном случае, каждый раз, когда вы будете запускать тестирование, вы будете получать все больше и больше записей в базе данных.

Лично я думаю, что использовать утверждение вроде этого:

$this->assertEquals(1, Order::count())

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

$initialOrdersCount = Order::count();

// here you run some actions you want to test

$this->assertSame($initialOrdersCount  + 1, Order::count());

Таким образом, если что-то еще произойдет в приложении или будет добавлено в тест, мне все равно, есть ли в базе данных 2 или 3 модели. Для меня важно, чтобы количество или заказы были увеличены на единицу.

...