Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using @dataProvider annotation of PHPunit doesnt work #668

Closed
Mohammad-Alavi opened this issue Apr 3, 2022 · 2 comments
Closed

Using @dataProvider annotation of PHPunit doesnt work #668

Mohammad-Alavi opened this issue Apr 3, 2022 · 2 comments
Assignees
Projects

Comments

@Mohammad-Alavi
Copy link
Member

Mohammad-Alavi commented Apr 3, 2022

Description:

If you create a dataProvider method with any kind of Laravel call in it (e.g. using a model factory), we get an error.

Expected Behavior:

It should work?

Additional Context:

Adding parent::setup to provider method seems to fix it?
A dataProvider method without any calls to Laravel, works as expected.
This might be a complication related to how Laravel loads and how PHPunit works.

Versions:

  • Apiato Version: v11 & v12
  • PHP Version: 8.1.0

Steps To Reproduce:

  1. Create a dataProvider method and use a model factory in it, e.g. User::factory()->create()
  2. Use @dataProvider annotation of PHPunit on your test and call the created dataProvider method
  3. Run the test
@Mohammad-Alavi Mohammad-Alavi created this issue from a note in v11 (To do) Apr 3, 2022
@Mohammad-Alavi Mohammad-Alavi self-assigned this May 10, 2022
@Mohammad-Alavi
Copy link
Member Author

Mohammad-Alavi commented Nov 16, 2022

A potential lead.

@Mohammad-Alavi
Copy link
Member Author

Mohammad-Alavi commented Jun 13, 2023

This is not an Apiato bug.

As explained here:

PHPUnit will call the data provider methods before running any tests. Before each test it will also call the setUp() method in the test case. Laravel hooks into the setUp() method to call $this->createApplication() which will add the controller classes to the 'include path' so that they can be autoloaded correctly.

Here are two ways to get around this, and I prefer the second one.

  1. Call refreshApplication() in your test setUp() method.
    protected function setUp(): void
    {
        parent::setUp();

        // I don't know if this impact performance or cause any problems with parallel testing.
        $this->refreshApplication();
    }
  1. User closure to defer the call to any Laravel functionalities (e.g. model factories) to when you actually use it.
    public function dataProvider(): array
    {
        return [
            [
                function () {
                    return [User::factory()->make()];
                },
            ],
            [
                fn () => [User::factory()->make()],
            ]
        ];
    }

    /**
     * @dataProvider dataProvider
     */
    public function testExample(Closure $data)
    {
        [$user] = $data();
        // If you use any data from the test class you need to bind the closure to it.
        // [$user] = $data->bindTo($this)();
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
v11
To do
Development

No branches or pull requests

1 participant