Skip to content

Instantly share code, notes, and snippets.

@lorisleiva
Created August 5, 2019 10:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lorisleiva/e4afa23e56e9172e66ce3e5381712b47 to your computer and use it in GitHub Desktop.
Save lorisleiva/e4afa23e56e9172e66ce3e5381712b47 to your computer and use it in GitHub Desktop.
✅ Set up traits dynamically for tests
<?php
namespace Tests;
use Tests\Authenticated;
use Illuminate\Support\Facades\Auth;
use Illuminate\Foundation\Testing\RefreshDatabase;
class ArticleUpdateTest extends TestCase
{
use RefreshDatabase;
use Authenticated;
/** @test */
public function authenticated_users_can_update_articles()
{
// User is already authenticated and accessible via $this->user.
$this->assertTrue(Auth::check());
$this->assertNotNull($this->user);
}
}
<?php
namespace Tests;
use App\User;
trait Authenticated
{
protected $user;
// This will be automatically set up on test classes that uses this trait.
public function setUpAuthenticated()
{
$this->user = factory(User::class)->create();
$this->actingAs($this->user);
}
}
<?php
namespace Tests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
abstract class TestCase extends BaseTestCase
{
use CreatesApplication;
protected function setUp(): void
{
// Set up traits dynamically.
// Uses the naming convention: "setUpNameOfMyTrait".
$this->afterApplicationCreated(function () {
foreach (class_uses_recursive($this) as $trait) {
if (method_exists($this, $method = 'setUp' . class_basename($trait))) {
call_user_func([$this, $method]);
}
}
});
parent::setUp();
}
}
@Naoray
Copy link

Naoray commented Aug 5, 2019

You can also use the following:

<?php

namespace Tests;

use Illuminate\Foundation\Testing\TestCase as BaseTestCase;

abstract class TestCase extends BaseTestCase
{
    use CreatesApplication;

    /**
     * Boot the testing helper traits.
     *
     * @return array
     */
    protected function setUpTraits()
    {
        $uses = parent::setUpTraits();

        foreach($uses as $trait) {
            if (method_exists($this, $method = 'setUp' . class_basename($trait))) {
                call_user_func([$this, $method]),
            }
        }
    }
}

@lorisleiva
Copy link
Author

lorisleiva commented Aug 5, 2019

@Naoray Yeah, I use to override that instead but I recently found out about afterApplicationCreatedCallbacks and I thought that was more robust than overriding a protected method.

Also parent::setUpTraits() returns an array of traits flipped. Which means you should use the key instead of the value when looping through them.

protected function setUpTraits()
{
    $uses = parent::setUpTraits();

    foreach($uses as $trait => $flippedIndex) {
        if (method_exists($this, $method = 'setUp' . class_basename($trait))) {
            call_user_func([$this, $method]);
        }
    }

    return $uses;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment