I’m currently writing feature tests for my application. Most of my tests must be initialized by creating a new User using factory.
I could do set up this with setUp method for each specific test but I thought it would be more convenient to create custom Traits as the specifications may vary between tests.
I’m following this article which, written for Laravel, to create custom traits for tests: https://medium.com/@SlyFireFox/laravel-tips-making-your-own-trait-hooks-for-tests-770f0aeda3c9
With this implementation, the setUpTraits method inside the TestCase.php file returns null and thus I’m unable to call the setUpUser method from the trait.
How should I fix this or is it even possible to set up custom traits for testing purposes with Lumen? I couldn’t find anything on Google.
Underneath is what I’ve tried so far.
Folder structure:
tests/
├── AuthenticationTest.php
├── Support
│ └── Authentication.php
└── TestCase.php
Since Lumen does not use namespacing for tests folder out of the box, I’ve modified composer.json as per following:
...
"autoload-dev": {
"classmap": [
"tests/"
],
"psr-4": {
"Tests\": "tests/"
}
},
...
Here’s how my TestCase.php file looks like:
<?php
use LaravelLumenTestingTestCase as BaseTestCase;
use TestsSupportAuthentication;
abstract class TestCase extends BaseTestCase
{
protected $base_path = '/api/v1';
protected $headers = ['Accept' => 'application/json'];
public function createApplication()
{
return require __DIR__.'/../bootstrap/app.php';
}
protected function setUpTraits()
{
$uses = parent::setUpTraits(); // $uses = null
if (isset($uses[Authentication::class])) {
$this->setUpUser();
}
}
}
Here’s my Trait:
<?php
namespace TestsSupport;
use AppModelsUser;
trait Authentication
{
protected $user;
public function setUpUser()
{
$this->user = User::factory()->create();
}
}
And here’s my test where I’m trying to call that trait:
<?php
use LaravelLumenTestingDatabaseTransactions;
use TestsSupportAuthentication;
class AuthenticationTest extends TestCase
{
use DatabaseTransactions;
use Authentication;
public function testUserAbleToAuthenticateWithValidCredentials() : void
{
$this->post(
$this->base_path . '/auth',
['username' => $this->user->username, 'password' => $this->user->password],
$this->headers
)->seeStatusCode(200)
->seeJsonStructure(['data' => ['token', 'token_type', 'expires_in']]);
}
}