Comments (28)
I think using MySQL will be a last resort. I want to run in memory, so that my tests run quickly.
from laravel-multitenancy.
Closing this as this is not a problem for the package tests, and it's also not an issue in our projects. If you find a solution, feel free to post it below, might be helpful for others.
from laravel-multitenancy.
Using Tenant::first()->makeCurrent()
and Tenant::current()->forget()
, or if you like:
Tenant::first()->execute(function () {
// all your tenant-aware tests :)
});
from laravel-multitenancy.
I just want to share how to configure the unit tests in my environment using Laravel v9 (as I was a bit lost about):
How to configure the unit tests for spatie/laravel-multitenancy package
On your test you need to replace RefreshDatabase
with TenantAware
:
namespace Tests\Feature;
use Tests\TestCase;
use App\Models\Tenant;
use Tests\Concerns\TenantAware;
class ExampleTest extends TestCase
{
use TenantAware;
public function testExample()
{
$this->assertTrue(Tenant::checkCurrent());
}
}
from laravel-multitenancy.
You can't switch a :memory: database
from laravel-multitenancy.
How do you do any automated testing then?
Somehow I need to configure two databases (landlord and one tenant) and be able to test against them.
from laravel-multitenancy.
Yes, sure: it's what we already done in our tests. You can use MySQL.
from laravel-multitenancy.
If you'll find a solution, keep us updated. Thanks
from laravel-multitenancy.
How to you TDD when using this package? Using MySQL instead of SQLite?
from laravel-multitenancy.
yes
from laravel-multitenancy.
Me too, I find that using MySQL is far more easier that SQLite. In SQLite certain functions (and json handling) doesn't exist or is a bit different than in MySQL.
from laravel-multitenancy.
IMHO it's better to test your application with the same database that you will use in the production environment: it will improve the test experience, and the feedback is more near to real.
from laravel-multitenancy.
OK, I'm going to give it a go.
I'd love to see your testing config (phpunit.xml, database.php) for running tests against landlords and tenants.
from laravel-multitenancy.
I have a tenant db and a landlord db set up for testing (MySQL). How do you switch in a test?
from laravel-multitenancy.
I am doing that in a test:
Tenant::first()->makeCurrent();
When I look a the connection, it is still connected to the landlord:
result = {Illuminate\Database\MySqlConnection} [18]
resolvers = {array} [0]
pdo = {Doctrine\DBAL\Driver\PDOConnection} [0]
readPdo = null
database = "landlord"
and \DB::select('SHOW TABLES')
Shows tables from the landlord.
Am I doing something silly?
phpunit
<server name="DB_CONNECTION" value="landlord"/>
<server name="DB_DATABASE" value="landlord"/>
database.php
'landlord' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('LANDLORD_DB_HOST'),
'port' => env('LANDLORD_DB_PORT'),
'database' => env('LANDLORD_DB_DATABASE'),
'username' => env('LANDLORD_DB_USERNAME'),
'password' => env('LANDLORD_DB_PASSWORD'),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
'tenant' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('TENANT_DB_HOST'),
'port' => env('TENANT_DB_PORT'),
'database' => env('TENANT_DB_DATABASE'),
'username' => env('TENANT_DB_USERNAME'),
'password' => env('TENANT_DB_PASSWORD'),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
.env
DB_CONNECTION=landlord
LANDLORD_DB_HOST=mysql
LANDLORD_DB_PORT=3306
LANDLORD_DB_DATABASE=landlord
LANDLORD_DB_USERNAME=default
LANDLORD_DB_PASSWORD=secret
TENANT_DB_HOST=mysql
TENANT_DB_PORT=3306
TENANT_DB_DATABASE=null
TENANT_DB_USERNAME=default
TENANT_DB_PASSWORD=secret
multitenancy.php
'tenant_finder' => Spatie\Multitenancy\TenantFinder\DomainTenantFinder::class,
'tenant_database_connection_name' => 'tenant',
'landlord_database_connection_name' => 'landlord',
'switch_tenant_tasks' => [
// add tasks here
Spatie\Multitenancy\Tasks\SwitchTenantDatabaseTask::class,
],
from laravel-multitenancy.
OK, I'm an idiot. I was it expecting it to swap the DB:connection()
but it doesn't.
The package sets the configuration for the tenant db and the models then use the correct db (via the traits).
Neat!
from laravel-multitenancy.
@ArtisanTinkerer Actually MySQL is faster than SQlite:
- Use
DatabaseTransactions
- Migrate your test DB
php artisan migrate --database=mysql_testing
Pros
You can use any MySQL function like DATE_FORMAT, tmp.category_name->>"$.'.$lang.'" as fmt_category_name
You can make sure that your foreign key constraints will work in production
Cons
You have to migrate your test DB php artisan migrate --database=mysql_testing
just like your local DB
I'm getting :
Time: 3.13 minutes, Memory: 596.00 MB
OK (1508 tests, 7787 assertions)
from a 4 years old HP running Ubuntu Budgie 18.04 with HDD
from laravel-multitenancy.
Hi, php artisan test
runs fine, but when I try to run php artisan test -p
it throws errors. Any suggestions?
from laravel-multitenancy.
@gssoftnepal what's the error?
from laravel-multitenancy.
I am using Laravel Sail with multiple databases, when I run php artisan test -p
, I get this error Illuminate\Database\QueryException: SQLSTATE[42000]: Syntax error or access violation: 1044 Access denied for user 'sail'@'%' to database '_test_4' (SQL: drop database if exists
_test_4)
from laravel-multitenancy.
I am using Laravel Sail with multiple databases, when I run
php artisan test -p
, I get this errorIlluminate\Database\QueryException: SQLSTATE[42000]: Syntax error or access violation: 1044 Access denied for user 'sail'@'%' to database '_test_4' (SQL: drop database if exists
_test_4)
You need to run sail artisan test
from laravel-multitenancy.
At first I ran sail shell
and then ran php artisan test
. This runs fine. I also ran sail artisan test
in my local terminal, it also runs fine, but when I run php artisan test -p
or sail artisan test -p
, all of my tests fail and I get this error: Illuminate\Database\QueryException: SQLSTATE[42000]: Syntax error or access violation: 1044 Access denied for user 'sail'@'%' to database '_test_4' (SQL: drop database if exists _test_4)
from laravel-multitenancy.
@adarmanto Thanks for sharing. But i'm getting this error running php artisan test
:
There is no active transaction
at vendor/laravel/framework/src/Illuminate/Database/Concerns/ManagesTransactions.php:291
287▕ */
288▕ protected function performRollBack($toLevel)
289▕ {
290▕ if ($toLevel == 0) {
➜ 291▕ $this->getPdo()->rollBack();
292▕ } elseif ($this->queryGrammar->supportsSavepoints()) {
293▕ $this->getPdo()->exec(
294▕ $this->queryGrammar->compileSavepointRollBack('trans'.($toLevel + 1))
295▕ );
+2 vendor frames
3 tests/Concerns/TenantAware.php:106
Illuminate\Database\Connection::rollBack()
Note: I have only one test exactly like yours above.
EDIT
I was creating the tenant table in the createDatabase
method as follows:
Schema::createDatabase($this->getDatabaseName());
I upgraded using the DB facade and I no longer have a transaction problem (like your example):
\DB::connection($this->tenantDatabaseConnectionName())->statement("CREATE DATABASE {$this->getDatabaseName()}");
from laravel-multitenancy.
@adarmanto Just a small point, how do you deal with the fact that when you do php artisan test
, it will create a tenant and its database, but the second time you run this command it will not work because the testing_tenant_db
database already exists?
from laravel-multitenancy.
@valh1996 in your case, you can skip creating the tenant database on testing like so:
if (! app()->runningUnitTests()) {
// Skip the tenant DB creation
}
Note: this is one of my reason to put the tenant DB creation into Queue so either I can mock it to skip it while testing and also test it as my example.
from laravel-multitenancy.
@adarmanto Thank you.
I ended up just adding IF NOT EXISTS
when creating a new database:
DB::connection($this->tenantDatabaseConnectionName())->statement("CREATE DATABASE IF NOT EXISTS {$this->getDatabaseName()}");
Let me ask you another question, how do you deal with laravel built-in asserts like $this->assertAuthenticated();
, it always uses the landlord connection. Any idea please?
from laravel-multitenancy.
@valh1996 I put the authentication tables (users, password_reset, etc) into the landlord database, but set the tenant
connection as my default DB and there is no issue when running default-generated tests from Starter Kit (using Inertia in my case). Don't forget to use Spatie\Multitenancy\Models\Concerns\UsesLandlordConnection
trait in any models that use landlord
connection.
from laravel-multitenancy.
@adarmanto I see, I use landlord as default connection. I have authentication at the landlord level, then in each tenant. Thanks for you response.
from laravel-multitenancy.
Related Issues (20)
- MakeQueueTenantAwareAction seems to break active requests when Queue Connection is sync HOT 4
- base table or view not found with AWS SQS queue for job TenantAware HOT 15
- randomly receive Invalid catalog name: 1046 No database selected (Connection: mysql, SQL: insert into failed_jobs (uuid, connection, queue, payload, exception, failed_at) on queue sqs HOT 5
- Tenant Aware Queue Fails No Database Selected when running from supervisor in a multi tenant environment using AWS SQS FIFO HOT 2
- Update documentation at https://spatie.be to `v3` HOT 3
- in_array(): Argument #2 ($haystack) must be of type array, null given {"exception":"[object] (TypeError(code: 0): in_array(): Argument #2 ($haystack) must be of type array, null given at /spatie/laravel-multitenancy/src/Actions/MakeQueueTenantAwareAction.php:79) HOT 1
- Cache issue with spatie/laravel-permission in TenantAware Command HOT 5
- Issue with the has function on different connections HOT 1
- I want to Connect to mongo DB for some tables but it is giving "Database connection [mongodb] not configured.", exception: "InvalidArgumentException",…} error
- Custom cache driver missing when switching Tenant HOT 4
- Cannot schedule jobs in Laravel 11 HOT 3
- Can't make route not tenant aware
- Erro during Laravel 11 for Notification multitenacy for multi-database
- Problem to install in Laravel 11 HOT 1
- Laravel 11: Multiple database does not switch and use tenant database HOT 2
- NeedsTenant with route model binding HOT 4
- Spatie\Multitenancy\Concerns\UsesMultitenancyConfig should be moved to ImplementsTenant? HOT 2
- getConnectionName() not compatible - ?string
- Session store not set on request HOT 3
- Switching tenants in the jobs queue HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from laravel-multitenancy.