Skip to content

Commit f550c6e

Browse files
authored
Create documentation about testing
Getting started with testing. Related to tenancy/multi-tenant#627.
1 parent 0f23b21 commit f550c6e

File tree

1 file changed

+182
-0
lines changed

1 file changed

+182
-0
lines changed

docs/hyn/5.3/testing

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
---
2+
title: Testing
3+
icon: fal fa-vial
4+
---
5+
6+
If you want to run tests for your tenant-related code, and benefit from the speed-boost
7+
given by an in-memory SQLite database, you will need to do a few things.
8+
9+
## Add some helper classes to your test environment
10+
11+
### A driver for SQLite
12+
13+
```php
14+
<?php
15+
16+
namespace Tests\Infrastructure;
17+
18+
class TestSQLiteDriver implements DatabaseGenerator
19+
{
20+
public function created(Created $event, array $config, Connection $connection): bool
21+
{
22+
return true;
23+
}
24+
25+
public function updated(Updated $event, array $config, Connection $connection): bool
26+
{
27+
return true;
28+
}
29+
30+
public function deleted(Deleted $event, array $config, Connection $connection): bool
31+
{
32+
return true;
33+
}
34+
}
35+
```
36+
37+
### A base test case for all tenant-related tests
38+
39+
```php
40+
<?php
41+
42+
namespace Tests\Infrastructure;
43+
44+
use Hyn\Tenancy\Contracts\CurrentHostname;
45+
use Hyn\Tenancy\Contracts\Repositories\HostnameRepository;
46+
use Hyn\Tenancy\Contracts\Repositories\WebsiteRepository;
47+
use Hyn\Tenancy\Models\Hostname;
48+
use Hyn\Tenancy\Models\Website;
49+
use Hyn\Tenancy\Providers\Tenants\RouteProvider;
50+
use Tests\Infrastructure\Database\TestSQLiteDriver;
51+
52+
abstract class TenantAwareTestCase extends TestCase
53+
{
54+
protected $website;
55+
protected $hostname;
56+
57+
protected function setUp()
58+
{
59+
parent::setUp();
60+
61+
$this->registerTestDatabaseDriver();
62+
$this->bypassTenantConnectionSettings();
63+
64+
$this->migrateSystemDatabase();
65+
[$this->website, $this->hostname] = $this->createTestTenant();
66+
67+
$this->setTenantDatabaseConnectionConfig();
68+
$this->setCurrentHostname($this->hostname);
69+
$this->registerTenantRoutes();
70+
$this->migrateTenantDatabase();
71+
}
72+
73+
protected function migrateSystemDatabase(): void
74+
{
75+
$this->artisan('migrate:fresh', [
76+
// this is a connection name, not a database name!!!
77+
'--database' => 'system',
78+
'--force' => true,
79+
'--path' => \database_path('migrations'),
80+
'--realpath' => true,
81+
]);
82+
}
83+
84+
protected function migrateTenantDatabase(): void
85+
{
86+
$this->artisan('migrate:fresh', [
87+
// this is a connection name, not a database name!!!
88+
'--database' => 'tenant',
89+
'--force' => true,
90+
'--path' => config('tenancy.db.tenant-migrations-path'),
91+
'--realpath' => true,
92+
]);
93+
}
94+
95+
protected function registerTenantRoutes(): void
96+
{
97+
(new RouteProvider(app()))->boot();
98+
}
99+
100+
protected function setCurrentHostname(Hostname $hostname): void
101+
{
102+
app()->singleton(CurrentHostname::class, function () use ($hostname) {
103+
return $hostname;
104+
});
105+
}
106+
107+
protected function setTenantDatabaseConnectionConfig(): void
108+
{
109+
config([
110+
'database.connections.tenant' => [
111+
'driver' => 'sqlite',
112+
'database' => ':memory:',
113+
],
114+
]);
115+
}
116+
117+
protected function createTestTenant(): array
118+
{
119+
$website = new Website();
120+
app(WebsiteRepository::class)->create($website);
121+
122+
$hostname = new Hostname();
123+
$hostname->fqdn = 'testing.example.com';
124+
$hostname = app(HostnameRepository::class)->create($hostname);
125+
app(HostnameRepository::class)->attach($hostname, $website);
126+
127+
return [$website, $hostname];
128+
}
129+
130+
protected function registerTestDatabaseDriver(): void
131+
{
132+
app('tenancy.db.drivers')->put('sqlite', TestSQLiteDriver::class);
133+
}
134+
135+
protected function bypassTenantConnectionSettings(): void
136+
{
137+
config(['tenancy.db.tenant-division-mode' => 'bypass']);
138+
}
139+
}
140+
141+
```
142+
143+
## Check the configuration files
144+
145+
### config/database.php
146+
147+
````php
148+
'system' => [
149+
'driver' => env('TENANCY_DRIVER', 'mysql'),
150+
'host' => env('TENANCY_HOST', '127.0.0.1'),
151+
'port' => env('TENANCY_PORT', '3306'),
152+
'database' => env('TENANCY_DATABASE', 'tenancy'),
153+
'username' => env('TENANCY_USERNAME', 'tenancy'),
154+
'password' => env('TENANCY_PASSWORD', ''),
155+
'unix_socket' => env('DB_SOCKET', ''),
156+
'charset' => 'utf8mb4',
157+
'collation' => 'utf8mb4_unicode_ci',
158+
'prefix' => '',
159+
'strict' => true,
160+
'engine' => null,
161+
],
162+
```
163+
164+
## Update your phpunit configuration
165+
166+
You need to indicate to PHP Unit that you want to use SQLite as your database.
167+
168+
```xml
169+
<env name="DB_CONNECTION" value="system"/>
170+
<env name="TENANCY_DRIVER" value="sqlite"/>
171+
<env name="TENANCY_DATABASE" value=":memory:"/>
172+
```
173+
174+
## Enjoy
175+
176+
You should now be ready to create your first test. Do not forget to extend the `TenantAwareTestCase`
177+
class instead of the default `TestCase` class.
178+
179+
## Troubleshooting
180+
181+
Make sure that PHPUnit is really using your own `PHPUnit.xml` configuration file. Else, the environment
182+
variables will not be taken into account.

0 commit comments

Comments
 (0)