Because you asked for Laravel magic... Here it goes. Probably an overkill and over engineered way.
Let's first create an interface whose sole purpose is to define a function that returns a connection string.
app/Connection.php
namespace App;
interface Connection
{
public function getConnection();
}
Then let's create a concrete implementation that we can use in real world (production).
app/GlobalConnection.php
namespace App;
class GlobalConnection implements Connection
{
public function getConnection()
{
return 'global-connection';
}
}
And also another implementation we can use in our tests.
app/TestingConnection.php (you can also put this in your tests directory, but make sure to change the namespace to the appropriate one)
namespace App;
class TestingConnection implements Connection
{
public function getConnection()
{
return 'testing-connection';
}
}
Now let's go ahead and tell Laravel which concrete implementation we want to use by default. This can be done by going to the app/Providers/AppServiceProvider.php file and adding this bit in the register method.
app/Providers/AppServiceProvider.php
namespace App\Providers;
use App\Connection;
use App\GlobalConnection;
// ...
public function register()
{
// ...
$this->app->bind(Connection::class, GlobalConnection::class);
// ...
}
Let's use it in our model.
app/SomeModel.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class SomeModel extends Model
{
public function __construct(Connection $connection, $attributes = [])
{
parent::__construct($attributes);
$this->connection = $connection->getConnection();
}
// ...
}
Almost there. Now in our tests, we can replace the GlobalConnection implementation with the TestingConnection implementation. Here is how.
tests/Feature/ExampleTest.php
namespace Tests\Feature;
use Tests\TestCase;
use App\Connection;
use App\TestingConnection;
class ExampleTest extends TestCase
{
public function setUp(): void
{
parent::setUp();
$this->app->instance(Connection::class, TestingConnection::class);
}
/** @test */
public function your_test()
{
// $connection is 'testing-connection' in here
}
}
Code is untested, but should work. You can also create a facade to access the method statically then use Mockery to mock the method call and return a desired connection string while in testing.