Courses

Laravel API Code Review and Refactor

Feature/Unit Tests: Make them Work

The next thing I usually check is whether the project has tests. It means I can try to modify the code and run the tests to check if I didn't break anything.

And we do have some tests here:

But when I try to run them, I get an error:


Configuring Unit/Feature Tests

Well, yeah, I don't see the tests/Unit folder. And don't get me wrong: it's totally fine NOT to have Unit tests, staying only with Feature tests. But the default Laravel comes with the example Unit test:

tests/Unit/ExampleTest.php:

namespace Tests\Unit;
 
use PHPUnit\Framework\TestCase;
 
class ExampleTest extends TestCase
{
/**
* A basic test example.
*/
public function test_that_true_is_true(): void
{
$this->assertTrue(true);
}
}

In this case, the code author has deleted that example test with the full folder of tests/Unit. It may be fine, but the problem is that testing is still configured to run tests from the tests/Unit folder, which doesn't exist anymore:

phpunit.xml

<testsuites>
<testsuite name="Unit">
<directory>tests/Unit</directory>
</testsuite>
<testsuite name="Feature">
<directory>tests/Feature</directory>
</testsuite>
</testsuites>

So, we have two choices here:

  • Either create a tests/Unit empty folder
  • Or, specify in phpunit.xml that we will NOT run the Unit tests

I chose the latter.

<testsuites>
<testsuite name="Unit">
<directory>tests/Unit</directory>
</testsuite>
<testsuite name="Feature">
<directory>tests/Feature</directory>
</testsuite>

Now, let's try to rerun the tests. Here's the result:

Ok, so it's trying to run on a database that doesn't exist. Let's fix this.


MySQL or SQLite Database?

I've noticed this line in the phpunit.xml:

<env name="DB_DATABASE" value="testing"/>

This means that the tests will be executed on the default DB connection (MySQL, in my case) on the database named testing. So, we may follow this configuration and create an empty local database.

However, I have 50+ Laravel projects locally, and the vague name testing would add chaos to the database list.

So, I have two choices:

  • Create a separate MySQL database with a suffix the same as the main project, like project_test
  • Or, just revert to the default Laravel configuration to run tests on SQLite in memory

And I choose the latter.

phpunit.xml

<env name="DB_DATABASE" value="testing"/> <!-- [tl! --] -->
<env name="DB_CONNECTION" value="sqlite"/> <!-- -->
<env name="DB_DATABASE" value=":memory:"/> <!-- -->

Now, let's try to rerun the tests.

Now it works!

Notice: in some cases, you may prefer to choose MySQL for testing if your code uses specific MySQL features or functions that may not work in SQLite. However, I didn't see anything specific to MySQL in this project.

Here's the full GitHub commit for passing tests.

Previous: Intro and Styling with Laravel Pint

No comments yet…

avatar
You can use Markdown