How can I config laravel for testing mysql - laravel

When I run docker-compose run laravel.test php artisan test it run containers but after that
It return
error: failed switching to "php": unable to find user php: no matching
entries in passwd file
I use docker so my connection to db looks like
.env
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=laravel_api
DB_USERNAME=sail
DB_PASSWORD=password
database.php
'mysql' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'laravel_api'),
'username' => env('DB_USERNAME', 'sail'),
'password' => env('DB_PASSWORD', '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'),
]) : []
phpunit.xml
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true"
>
<testsuites>
<testsuite name="Unit">
<directory suffix="Test.php">./tests/Unit</directory>
</testsuite>
<testsuite name="Feature">
<directory suffix="Test.php">./tests/Feature</directory>
</testsuite>
</testsuites>
<coverage processUncoveredFiles="true">
<include>
<directory suffix=".php">./app</directory>
</include>
</coverage>
<php>
<env name="APP_ENV" value="local"/>
<env name="DB_CONNECTION" value="mysql"/>
<env name="BCRYPT_ROUNDS" value="4"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="MAIL_MAILER" value="array"/>
<env name="QUEUE_CONNECTION" value="sync"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="TELESCOPE_ENABLED" value="false"/>
</php>
</phpunit>
In docker-compose.yml I have
services:
laravel.test:
build:
etc...

Related

I got “There is no active transaction” error after I added RefreshDatabase into test file

Making in laravel 9.48.0 with mysql database http tests after I added RefreshDatabase into test file
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Foundation\Testing\Concerns\InteractsWithExceptionHandling;
use Tests\TestCase;
use App\Models\{Article, User};
use Illuminate\Support\Str;
class ArticlesCrudTest extends TestCase
{
use InteractsWithExceptionHandling;
use RefreshDatabase;
I got “There is no active transaction” error on 1st test from 15 tests in this file
I do not use sqllite, but other mysql database, so phpunit.xml have sqlite and memory options disabled:
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true"
printerClass="Sempro\PHPUnitPrettyPrinter\PrettyPrinterForPhpUnit9"
>
<testsuites>
<testsuite name="Unit">
<directory suffix="Test.php">./tests/Unit</directory>
</testsuite>
<testsuite name="Feature">
<directory suffix="Test.php">./tests/Feature</directory>
</testsuite>
</testsuites>
<coverage processUncoveredFiles="true">
<include>
<directory suffix=".php">./app</directory>
</include>
</coverage>
<php>
<env name="APP_ENV" value="testing"/>
<env name="BCRYPT_ROUNDS" value="4"/>
<env name="CACHE_DRIVER" value="array"/>
<!-- <env name="DB_CONNECTION" value="sqlite"/> -->
<!-- <env name="DB_DATABASE" value=":memory:"/> -->
<env name="MAIL_MAILER" value="array"/>
<env name="QUEUE_CONNECTION" value="sync"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="TELESCOPE_ENABLED" value="false"/>
</php>
</phpunit>
My control have code :
\Log::info( ' -1 store::');
DB::beginTransaction();
try {
$article = Article::create([
'title' => $data['title'],
'text' => $data['text'],
'text_shortly' => $data['text_shortly'],
'creator_id' => $data['creator_id'],
'published' => $data['published'],
]);
\Log::info( ' -2 store::');
DB::Commit();
$article->load('creator');
return response()->json(
['article' => (new ArticleResource($article))],
HTTP_RESPONSE_OK_RESOURCE_CREATED
); // 201
} catch (\Exception $e) {
DB::rollback();
}
In log file there are 2 lines from this controller. Before I added RefreshDatabase these tests worked ok, just like in real work.
What is wrong ?
Thanks!

Laravel test returns 404

I'm trying to run some tests but it is returning 404 after the first run. Sometimes it runs normally, but 90% of the time, it returns me a 404 response.
Pstoman request works 100% of the time.
First time running (the failure here is from another test):
Next times (now I'm getting the 404):
Here is my phpunit.xml
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true"
>
<testsuites>
<testsuite name="Unit">
<directory suffix="Test.php">./tests/Unit</directory>
</testsuite>
<testsuite name="Feature">
<directory suffix="Test.php">./tests/Feature</directory>
</testsuite>
</testsuites>
<coverage processUncoveredFiles="true">
<include>
<directory suffix=".php">./app</directory>
</include>
</coverage>
<php>
<server name="APP_ENV" value="testing"/>
<server name="APP_URL" value="http://localhost"/>
<server name="BCRYPT_ROUNDS" value="4"/>
<server name="CACHE_DRIVER" value="array"/>
<server name="DB_CONNECTION" value="sqlite"/>
<server name="DB_DATABASE" value=":memory:"/>
<server name="MAIL_MAILER" value="array"/>
<server name="QUEUE_CONNECTION" value="sync"/>
<server name="SESSION_DRIVER" value="array"/>
<server name="TELESCOPE_ENABLED" value="false"/>
</php>
</phpunit>
The test:
public function verify_username_should_return_id_when_existing_document()
{
$this->seed(UserTypeSeeder::class);
$user = User::factory()->create();
$response = $this->withHeaders([
'user_type' => $user->type->id,
])->postJson("api/auth/username", [
"username" => $user->document
]);
$response->assertOk()
->assertJson(["id" => 1]);
}
I found that for some reason if I change the $this->withHeaders(['user_type' => $user->type->id,]) to $this->withHeader("user_type", $user->type->id) it works but it doesn't make sense to me

Testing laravel api with jwt

I'm trying to write some test , the first test its for login route, I'm using jwt and mongodb, I set .env.testing identical to .env
DB_CONNECTION=mongodb
DB_HOST=127.0.0.1
DB_PORT=27017
DB_DATABASE=mydb
DB_USERNAME=myuser
DB_PASSWORD=mypass
this is phpunit.xml
<php>
<server name="APP_ENV" value="testing"/>
<server name="BCRYPT_ROUNDS" value="4"/>
<server name="CACHE_DRIVER" value="array"/>
<server name="DB_CONNECTION" value="sqlite"/>
<server name="DB_DATABASE" value=":memory:"/>
<server name="MAIL_DRIVER" value="array"/>
<server name="QUEUE_CONNECTION" value="sync"/>
<server name="SESSION_DRIVER" value="array"/>
</php>
I tried with <server name="DB_CONNECTION" value="mongodb/> but I get the same error
and this is the test
<?php
namespace Tests\Unit;
use Tests\TestCase;
class AuthTest extends TestCase
{
/**
* A basic unit test example.
*
* #return void
*/
public function test_if_login()
{
$response = $this->json('POST', 'http://127.0.0.1:8000/auth', [
'email' => 'usuario1',
'password' => '12345'
]);
$response
->assertStatus(200)
->assertJsonStructure([
'data'=>[
'token'
]
]);
}
}
but I get this error
There was 1 failure:
1) Tests\Unit\AuthTest::test_if_login
Expected status code 200 but received 500.
Failed asserting that false is true.
Not sure about what is the problem

Laravel Testing with Modules Test setup Migrations not run?

Laravel v5.5.48
Phpunit 6.5.14
Was able to setup the test to run from the real mysql database, but of course, this is not desirable. So, changed phpunit.xml to use sqlite, but now I get "No such table" errors.
Digged for hours, but cannot get past this error.
It seems that Migrations are not getting run into the Memory Database (my theory).
It is important to mention that our application has Asgard CMS, so it has many modules (in the Modules folder) and each has its own database/migrations folder where the 'true' migrations are kept.
The migration for the table setting__settings mentioned in the error, would be in the Module/Setting/database/migrations folder.
Error info:
PHPUnit 6.5.14 by Sebastian Bergmann and contributors.
Runtime: PHP 7.3.13
Configuration: /var/www/html/phpunit.xml
E
Time: 5.93 seconds, Memory: 10.00MB
There was 1 error:
1) Tests\Unit\ExampleTest::testBasicTest
Illuminate\Database\QueryException: SQLSTATE[HY000]: General error: 1 no such table: setting__settings (SQL: select * from "setting__settings" where "name" = sitesearch::base_path limit 1)
/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Connection.php:664
/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Connection.php:624
/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Connection.php:333
/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:1719
/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:1704
/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:481
/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:465
/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Concerns/BuildsQueries.php:77
/var/www/html/Modules/Setting/Repositories/Eloquent/EloquentSettingRepository.php:86
/var/www/html/Modules/Setting/Support/Settings.php:34
/var/www/html/Modules/Setting/helpers.php:6
/var/www/html/Modules/Sitesearch/Http/frontendRoutes.php:6
/var/www/html/Modules/Core/Providers/RoutingServiceProvider.php:76
/var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php:389
/var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php:349
/var/www/html/Modules/Core/Providers/RoutingServiceProvider.php:77
/var/www/html/Modules/Core/Providers/RoutingServiceProvider.php:61
/var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php:389
/var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php:349
/var/www/html/Modules/Core/Providers/RoutingServiceProvider.php:62
/var/www/html/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:29
/var/www/html/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:87
/var/www/html/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:31
/var/www/html/vendor/laravel/framework/src/Illuminate/Container/Container.php:549
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Support/Providers/RouteServiceProvider.php:74
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Support/Providers/RouteServiceProvider.php:33
/var/www/html/Modules/Core/Providers/RoutingServiceProvider.php:25
/var/www/html/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:29
/var/www/html/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:87
/var/www/html/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:31
/var/www/html/vendor/laravel/framework/src/Illuminate/Container/Container.php:549
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Application.php:792
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Application.php:775
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Application.php:776
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/BootProviders.php:17
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Application.php:213
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php:296
/var/www/html/tests/CreatesApplication.php:18
/var/www/html/vendor/orchestra/testbench-core/src/TestCase.php:71
/var/www/html/vendor/orchestra/testbench-core/src/Concerns/Testing.php:59
/var/www/html/vendor/orchestra/testbench-core/src/TestCase.php:41
How the TestCase is extended:
namespace Tests;
use Orchestra\Testbench\TestCase as BaseTestCase;
abstract class TestCase extends BaseTestCase
{
use CreatesApplication;
}
The test itself:
namespace Tests\Unit;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class ExampleTest extends TestCase
{
use RefreshDatabase;
/** #test */
public function testBasicTest()
{
$this->post(route('search_results'), ['search_term' => 'calgary'])
->assertStatus(200)
->assertViewIs('sitesearch::results.index')
->assertViewHas('search_term', 'calgary');
$this->assertTrue(true);
}
}
Phpunit.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="true"
stopOnFailure="true"
verbose="true">
<testsuites>
<testsuite name="Application Test Suite">
<testsuite name="Test Suite">
<directory>./tests/Unit</directory>
<directory>./Modules/*/Tests</directory>
<!-- <directory>./tests/Feature</directory>-->
</testsuite>
<!-- <testsuite name="Modules Test Suite">-->
<!-- <directory>./Modules/*/Tests</directory>-->
<!-- </testsuite>-->
</testsuite>
</testsuites>
<!-- UN-COMMENT & RUN TO GET CODE COVERAGE-->
<!-- <logging>-->
<!-- <log type="coverage-html" target="./coverage" charset="UTF-8"-->
<!-- yui="true" highlight="true" lowUpperBound="50" highLowerBound="80"-->
<!-- showUncoveredFiles="false" />-->
<!-- </logging>-->
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">./Modules/*/Tests</directory>
</whitelist>
</filter>
<php>
<env name="DB_CONNECTION" value="sqlite_memory" force="true"/>
<env name="APP_ENV" value="testing"/>
<env name="APP_URL" value=""/>
<env name="CACHE_DRIVER" value="array"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="QUEUE_DRIVER" value="sync"/>
</php>
</phpunit>
Also, added sqlite_memory to config/database.php:
'connections' => [
'sqlite_memory' => [
'driver' => 'sqlite',
'database' => ':memory:',
'prefix' => '',
],
'sqlite' => [
'driver' => 'sqlite',
'database' => env('DB_DATABASE', database_path('database.sqlite')),
'prefix' => '',
],

While running laravel phpunit testcase , i'm getting an error "Call to a member function connection() on null" in Model.php line 1249

I'm running laravel phpunit testcase, getting error in DB connection. DB connected successfully. But,
"Call to a member function connection() on null" - Could not open to
database connection server. Please update the configuration settings.
I did all those things properly. Find below details:
"php" : ">=7.1.3",
"laravel/lumen-framework": "5.8.*",
"phpunit/phpunit" : "^7.0",
"phpunit/php-invoker" : "*",
"phpunit/dbunit" : "^4.0",
This would be a bit of a guess without seeing your phpunit.xml configuration but I suspect you need to specify a connection for testing.
If you check your php unit file you should have some values like below in your php property.
Setting the DB_CONNECTION to sqlite and DB_DATABASE to :memory: is a fast and light-weight way to configure your testing DB.
<php>
<server name="APP_ENV" value="testing"/>
<server name="BCRYPT_ROUNDS" value="4"/>
<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>
<server name="CACHE_DRIVER" value="array"/>
<server name="MAIL_DRIVER" value="array"/>
<server name="QUEUE_CONNECTION" value="sync"/>
<server name="SESSION_DRIVER" value="array"/>
</php>
If you do have similar values in your phpunit.xml file then you will need to check your config/database.php file and ensure the connection matching your DB_CONNECTION has a sensible configuration.
The default values for sqlite should work fine and are as follows:
'sqlite' => [
'driver' => 'sqlite',
'database' => env('DB_DATABASE', database_path('database.sqlite')),
'prefix' => '',
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
],
Hope this helps.

Resources