Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Zuruck's avatar

Mocking Faker Generator

I'm working with Laravel 10 and starting to study testing and mocking. I've built a basic entity that has some simple properties and two images, that, for simplicity, I'm storing locally and saving the path relative to storage in the database. I've create the following factory for the model:

<?php
// ...
class SpaceFactory extends Factory
{
    public function definition(): array
    {
        return [
            'name' => $this->faker->company,
            'description' => $this->faker->sentence,
            'profile_path' => str_replace('storage/app/', '', $this->faker->image('storage/app/spaces')),
            'banner_path' => str_replace('storage/app/', '', $this->faker->image('storage/app/spaces')),
            'created_by' => User::factory()->create()->id,
        ];
    }
}

The main problem I have is while testing, the tests seems very slow and I'm pretty sure it's because I'm creating 40 fake images every time in the index method test

<?php
// ...
class SpaceTest extends TestCase
{
    use InteractsWithDatabase, RefreshDatabase;

    public function setUp(): void
    {
        parent::setUp();

        Storage::fake('local');
    }

    public function testUserCanListSpaces()
    {

        $mock = $this->partialMock(\Faker\Generator::class, function (\Mockery\MockInterface $mock) {
           $mock->shouldReceive('image')->times(40)->andReturn('mocked_path.png');
        });

        $spaces = Space::factory()->count(20)->create();


        $response = $this->getJson('/api/spaces');

        $response->assertOk();
        $response->assertJsonStructure([
            'results',
            'meta',
            'links'
        ]);
    }
}

I was able to mock the image method of \Faker\Generator::class and make it return a string while testing. The problem is that all the other formatters (I believe this is the name they use in faker?) are not implementend although I'm using a partial mock.

Test result while mocking faker generator: https://prnt.sc/1KcTy0HjuWx9

What can I do to partially mock faker correctly? Or perhaps should I change my factory to use another fake image generation method?]

0 likes
6 replies
Zuruck's avatar

@Sergiu17 Interesting, didn't know about these. Unfortunately they execute after the definition method so the images would still get generated. I could do withImages but that would make me opt-in for something that is necessary when creating the model. I think I could manipulate the definition attributes to check if the attributes have already been set and not execute faker if that's true

Sergiu17's avatar

@Zuruck what about this?

$spaces = Space::factory()->count(20)->create([
	'profile_path' => 'mocked_path.png',
	'banner_path' => 'mocked_path.png',
]);
Zuruck's avatar

@Sergiu17 Yeah tried that too, it uses mocked_path.png in the end but still creates the images, that's where the idea to check things inside definition came from 😄

MohamedTammam's avatar

You can test without creating images.

But my main questions are, why are you creating 40 instance in one test method? what is the need of them? Why not just one? does the test case differ from one instance to 40?

Zuruck's avatar

@MohamedTammam Aiming to test pagination, if only the correct amount of them would show up in the first page

Please or to participate in this conversation.