0

I need to make some fake records in laravel testing in a way that some of them have specific values.

for example I need to create 20 fake records of countries name and want to name the two records "USA" and "UK" and other values is not important.

If I use this code all records name will be same:

$country = Country::factory()->count(20)->create(['name'=> 'USA']);
rahman j89
  • 59
  • 8
  • 3
    I don't think you can achieve this in one single command. You'll need to call this twice with `count(1)` for US and UK. Then do a loop from 1 to 18 with a random string. – Andrea Olivato Mar 14 '22 at 16:45
  • No idea if Laravel supports this, but maybe you could define the value part of the array as a closure that returns a random value? `->create(['name' => function() { return ['USA', 'UK'][random_int(0, 1)]; })` – Alex Howansky Mar 14 '22 at 16:53
  • 1
    You can take advantage of [`Sequences`](https://laravel.com/docs/9.x/database-testing#sequences) but even that will not fully solve your issue. – matiaslauriti Mar 15 '22 at 13:45

2 Answers2

0

Why just use 2 lines?

Country::factory()->count(10)->create(['name'=> 'USA']);
Country::factory()->count(10)->create();

Or you can put into your factory like:

/**
 * Define the model's default state.
 *
 * @return array<string, mixed>
 */
public function definition()
{
    return [
        'name' => $this->faker->boolean ? $this->faker->randomElement(['USA', 'UK']) : null,
gguney
  • 2,512
  • 1
  • 12
  • 26
0

You can do it like this

$country = Country::factory()
    ->count(20)
    ->sequence(new Sequence(
        function($sequence) { 
            return $index === 0 ? 
            ['name' => 'UK'] : 
                $index === 1 ? 
                ['name' => 'USA'] : 
                ['name' => $this->faker->word()]; 
        }
    ))
    ->create();

That way, if the sequence is in its first iteration, name will be set to 'UK', second iteration will be 'USA', and after that a random word.

damask
  • 529
  • 4
  • 17