Symfony 5 - Unable to load fixtures with phpunit - php

I am trying to load my fixtures (php file) from phpunit.
I installed LiipTestFixture, and in my AbstractControllerTest.php :
<?php
namespace App\Tests\Controller;
use App\Entity\App\User;
use App\Services\App\EntrepriseServiceTest;
use Liip\TestFixturesBundle\Test\FixturesTrait;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Bundle\FrameworkBundle\KernelBrowser;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\BrowserKit\Cookie;
use Symfony\Component\Console\Tester\CommandTester;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
abstract class AbstractControllerTest extends WebTestCase
{
use FixturesTrait;
protected function setUp(): void
{
if (!$this->client) {
$this->client = static::createClient();
}
$this->loadFixtures([
"App\DataFixtures\AppFixtures",
])->getReferenceRepository();
}
My fixtures class :
class AppFixtures extends Fixture implements FixtureInterface
{
//...
}
But when I launch my tests, I've no error, but the fixtures don't charge.
Can someone help me please ?
PS: I'm using MySql database

Related

Unable to use factory() in Test's setUp() method in Laravel

I've encountered an error when refactoring my Laravel tests by adding at setUp() method.
This works as expected:
<?php
namespace Tests\Feature;
use App\Models\Person;
use Tests\TestCase;
class MembershipTicketsTest extends TestCase
{
public function test_a_non_member_cannot_list_redeemable_events()
{
$user = Person::factory()->create();
$this->actingAs($user);
$this->get(route('event.index'))->assertStatus(302)->assertRedirect(route('membership.create'));
}
Where as this returns the error Unknown formatter "firstName":
<?php
namespace Tests\Feature;
use App\Models\Person;
use Tests\TestCase;
class MembershipTicketsTest extends TestCase
{
protected $user;
protected function setUp() : void
{
$this->user = Person::factory()->create();
}
public function test_a_non_member_cannot_list_redeemable_events()
{
$this->actingAs($this->user);
$this->get(route('event.index'))->assertStatus(302)->assertRedirect(route('membership.create'));
}
Every solution to this error I've found says to make sure that you have use Tests\TestCase; in your file, which I do.
I presume this means I cannot use factories in the setUp() method of a test in Laravel. Is this true, and why is it the case?

Why console application fails to retrieve mocked service during testing?

I have the following console application:
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Services\Myservice;
class MyCommand extends Command
{
protected $signature = 'test';
public function handle(Myservice $service){
dump($service->dummy());
}
}
And I have the following service:
namespace App\Services;
class Myservice
{
public function dummy()
{
return false;
}
}
I also made the following test:
namespace Tests\Console;
use Illuminate\Foundation\Testing\TestCase;
use Mockery;
class TestMyCommand extends TestCase
{
public function testCommand()
{
$service = Mockery::mock(Myservice::class);
$service->shouldReceive('dummy')->andReturn(true);
app()->bind(MyService::class,$service);
$this->artisan('test')
$service->shouldHaveReceived('dummy')->andReturn(true);
}
}
But I retrieve the following error:
There was 1 error:
1) Tests\Console\TestMyCommand::testCommand
Mockery\Exception\InvalidCountException: Method dummy(<Any Arguments>) from Mockery_0__Tests_Console_MyService should be called
at least 1 times but called 0 times.
/var/www/html/api/vendor/mockery/mockery/library/Mockery/CountValidator/AtLeast.php:47
/var/www/html/api/vendor/mockery/mockery/library/Mockery/Expectation.php:312
/var/www/html/api/vendor/mockery/mockery/library/Mockery/ReceivedMethodCalls.php:46
/var/www/html/api/vendor/mockery/mockery/library/Mockery/VerificationDirector.php:36
/var/www/html/api/tests/Console/MyCommand.php:20
So why I am unable to provide a mocked service to the command?
#Edit 1:
I tried the following:
<?php
namespace Tests\Console;
use Illuminate\Foundation\Testing\TestCase;
use Tests\CreatesApplication;
use Mockery;
class TestMyCommand extends TestCase
{
use CreatesApplication;
public function testCommand()
{
$service = Mockery::mock(Myservice::class);
$service->shouldReceive('dummy')->andReturn(true);
app()->instance(MyService::class,$service);
$this->artisan('test');
$service->shouldHaveReceived('dummy')->andReturn(true);
}
}
And the following:
<?php
namespace Tests\Console;
use Illuminate\Foundation\Testing\TestCase;
use Tests\CreatesApplication;
use Mockery;
class TestMyCommand extends TestCase
{
use CreatesApplication;
public function testCommand()
{
$service = Mockery::mock(Myservice::class);
$service->shouldReceive('dummy')->andReturn(true);
$this->app->instance(MyService::class,$service);
$this->artisan('test');
$service->shouldHaveReceived('dummy')->andReturn(true);
}
}
But still get the error:
Time: 3.32 seconds, Memory: 38.00 MB
There was 1 error:
1) Tests\Console\TestMyCommand::testCommand
Mockery\Exception\InvalidCountException: Method dummy(<Any Arguments>) from Mockery_0__Tests_Console_Myservice should be called
at least 1 times but called 0 times.
/var/www/html/api/vendor/mockery/mockery/library/Mockery/CountValidator/AtLeast.php:47
/var/www/html/api/vendor/mockery/mockery/library/Mockery/Expectation.php:312
/var/www/html/api/vendor/mockery/mockery/library/Mockery/ReceivedMethodCalls.php:46
/var/www/html/api/vendor/mockery/mockery/library/Mockery/VerificationDirector.php:36
/var/www/html/api/tests/Console/TestMyCommand.php:21
ERRORS!
Tests: 1, Assertions: 2, Errors: 1.
Generating code coverage report in HTML format ... done

AsserEquals not found in WebTestCase Symfony

I have a WebTestCase class:
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Bundle\FrameworkBundle\Client;
class ApiAdminInvoiceControllerTest extends WebTestCase
{
public function test()
{
...
$this->assertArrayHasKey('id', $array);
...
}
}
I have this error in all asserts:Method 'assertArrayHasKey' not found.
Try using PHPUnit\Framework\TestCase; as base class

Deleting models from database after Laravel Dusk tests have run?

I'm just starting out with looking at Dusk - and I'm testing some user functionality.
Below is my current test, however I'm trying to clean up after myself - for example the newly created user should be deleted from the database once it's done.
I've tried to use a tearDown method, but it doesn't seem to be be actually deleting it.
How would I typically go about spinning up temp models which need to be garbaged after?
<?php
namespace Tests\Browser;
use App\User;
use Tests\DuskTestCase;
use Illuminate\Foundation\Testing\DatabaseMigrations;
class LoginTest extends DuskTestCase
{
protected $user = null;
public function testIfPublicUsersLogin()
{
$this->user = $user = factory(User::class)->create([
'is_student' => 0
]);
$this->browse(function ($browser) use ($user) {
$browser->visit('/login')
->assertVisible('#email')
->type('#email', $user->email)
->type('#password', 'secret')
->press('#loginButton')
->assertPathIs('/play');
});
}
public function tearDown()
{
if ($this->user) {
User::destroy($this->user->id);
//$this->user->delete();
}
}
}
There are multiple ways to achieve this:
Use the DatabaseTransactions trait so that there's a transaction rollback after every test. To do so add: use Illuminate\Foundation\Testing\DatabaseTransactions; in your php file and add use DatabaseTransactions; in your test class
You might want to use the DatabaseMigrations trait if you want to migrate and migrate rollback before and after every test rather than wrap them into transactions. To do so add: use Illuminate\Foundation\Testing\DatabaseMigrations; in your php file and add use DatabaseMigrations; in your test class
If you want to use custom setup and teardown methods, use the
afterApplicationCreated and beforeApplicationDestroyed methods
instead to register callbacks
<?php
namespace Tests\Browser;
use App\User;
use Tests\DuskTestCase;
use Illuminate\Foundation\Testing\DatabaseMigrations;
class LoginTest extends DuskTestCase
{
protected $user = null;
public function testIfPublicUsersLogin()
{
$this->user = $user = factory(User::class)->create([
'is_student' => 0
]);
$this->browse(function ($browser) use ($user) {
$browser->visit('/login')
->assertVisible('#email')
->type('#email', $user->email)
->type('#password', 'secret')
->press('#loginButton')
->assertPathIs('/play');
$user->delete();
});
}
}
this code line $user->deletedelete your data after test. The tearDown method is useless.

PhalconPHP - Unable to load a component from the DI in a controller

I am trying to create an ACL component as a service, for a multi-module PhalconPHP application. When I call the ACL component from the Controller Base, I am getting an error that I can't re-declare the ACL class.
Any ideas how to fix it, and understand the logic of why it is re-initialized again?
Fatal error: Cannot declare class X\Acl\Acl because the name is already in use in C:\xampp\htdocs\x\app\common\Acl\Acl.php on line 12
Update:
If I changed everything to "Pacl" then it works. I assume there might be a mixup with the PhalconPHP namespace. I am either not using the namespaces properly, or there's a bug in PhalconPHP 2.1 Beta 2.
/app/common/Acl/Acl.php
namespace X\Acl;
use Phalcon\Mvc\User\Component;
use Phalcon\Acl;
use Phalcon\Acl\Role as AclRole;
use Phalcon\Acl\Resource as AclResource;
/*
* ACL component
*/
class Acl extends Component {
private function initialize() {
}
public function isAllowed() {
die('called');
}
}
/app/front/controllers/ControllerBase.php
namespace X\Front\Controllers;
use Phalcon\Session as Session;
use Phalcon\Mvc\Controller;
use Phalcon\Mvc\Dispatcher;
class ControllerBase extends Controller {
public function beforeExecuteRoute(Dispatcher $dispatcher) {
//$this->acl = $this->getDI()->get("acl");
var_dump($this->acl->isAllowed()); //same behavior in both case
}
}
/app/front/Module.php
namespace X\Front;
use Phalcon\DiInterface;
use Phalcon\Mvc\Dispatcher;
use X\Acl\Acl as Acl;
class Module {
public function registerAutoloaders() {
$loader = new \Phalcon\Loader();
$loader->registerNamespaces(array(
'X\Front\Controllers' => __DIR__ . '/controllers/',
'X\Front' => __DIR__,
'X' => __DIR__ . '/../common/'
));
$loader->register();
}
public function registerServices(DiInterface $di) {
$di['acl'] = function() {
return new Acl();
};
}
}
This is not Phalcon issue. Look closely at your code:
namespace X\Acl;
use Phalcon\Acl;
class Acl extends ... {
}
What Acl interpreter should use? X\Acl\Acl or Phalcon\Acl?
The same error you get for example for the following code
namespace My\Awesome\Ns;
use Some\Name; # Name 1
class Name # Name 2
{
}

Categories