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?
Related
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
I updated a backpack project from backpack 4.0 to 4.1 and followed the upgrade guide that is provided on the backpack site. Laravel still runs on 6.x and has not been upgraded lately.
The list and /edit update views are working as intended. Only when trying to open a show view (happens on all models), then the following error occurs:
Too few arguments to function Illuminate\Database\Eloquent\Model::created(), 0 passed in /var/www/vendor/backpack/crud/src/app/Library/CrudPanel/CrudPanel.php on line 330 and exactly 1 expected
I tried to follow the stack trace but I can't find the source that throws the error. I also tried to remove all the methods from one model and just keep construct() and setup() and even then the errors is still thrown.
Edit: The error occurs for all models, this is the code of one random model.
namespace App\Models;
use Backpack\CRUD\app\Models\Traits\CrudTrait;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Vereine extends KVUser
{
}
namespace App\Models;
use Backpack\CRUD\app\Models\Traits\CrudTrait;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class KVUser extends Model
{
use CrudTrait;
use SoftDeletes;
protected $table = 'user';
public $incrementing = true;
/*
|--------------------------------------------------------------------------
| GLOBAL VARIABLES
|--------------------------------------------------------------------------
*/
protected $guarded = [];
public function __construct(array $attributes = [])
{
$this->creating([$this, 'onCreating']);
$this->updating([$this, 'onUpdating']);
parent::__construct($attributes);
}
public static function deleting($callback)
{
parent::deleting($callback);
$callback->update(['deleted' => 1]);
}
public function onCreating(\App\Models\KVUser $row)
{
// Placeholder for catching any exceptions
if (!\Auth::user()->id) {
return false;
}
$row->setAttribute('created_id', \Auth::user()->id);
}
public function onUpdating(\App\Models\KVUser $row)
{
// Placeholder for catching any exceptions
if (!\Auth::user()->id) {
return false;
}
$row->setAttribute('updated_id', \Auth::user()->id);
}
}
namespace App\Http\Controllers\Admin;
use App\Http\Requests\VereineRequest;
use App\Models\Vereine;
use Backpack\CRUD\app\Http\Controllers\CrudController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
class VereineCrudController extends CrudController
{
use \Backpack\CRUD\app\Http\Controllers\Operations\ListOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\CreateOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\UpdateOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\DeleteOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\ShowOperation;
public function __construct()
{
parent::__construct();
}
public function setup()
{
$this->crud->setModel('App\Models\Vereine');
$this->crud->setRoute(config('backpack.base.route_prefix') . '/vereine');
$this->crud->setEntityNameStrings('Verein', 'Vereine');
$this->crud->setListView('vendor/backpack/crud/vereine/vereine_list');
$this->crud->setShowView('vendor/backpack/crud/vereine/vereine_show');
}
}
Screenshot Error Message
I would really appreciate some help - thank you!
For clearly to identify error you should attached image. Thanks
I'm trying to test a policy for the index method of my controller. I'm passing the class name into the authorize helper, but I'm receiving a 500 status and an error that says
1)
Tests\Feature\FunderFeatureTest::an_admin_should_be_able_to_view_a_list_of_funders
Symfony\Component\Debug\Exception\FatalThrowableError: Too few
arguments to function App\Policies\FunderPolicy::view(), 1 passed in
/home/vagrant/code/rtl/vendor/laravel/framework/src/Illuminate/Auth/Access/Gate.php
on line 614 and exactly 2 expected
What am I doing wrong? All other policies work (including the create() and store() methods which do not require a model). I realize this is similar to many other questions on SO, however the majority seem to be due to the fact that people weren't passing the class name to the authorize method or the problem occurs on a different controller method (such as update()). My apologies if this specific question was asked before, I've been researching this off an on for two weeks and can't quite find the answer I'm looking for.
FundersController.php
namespace App\Http\Controllers;
use App\Funder;
use Illuminate\Http\Request;
class FundersController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function index()
{
$this->authorize('view', Funder::class);
return view('funders.index', [
'funders' => Funder::all(),
]);
}
}
FunderPolicy.php
namespace App\Policies;
use App\User;
use App\Funder;
use Illuminate\Auth\Access\HandlesAuthorization;
class FunderPolicy
{
use HandlesAuthorization;
public function view(User $user, Funder $funder)
{
return ($user->isAdmin() || $user->isSuperAdmin());
}
}
FunderFeatureTest.php (For reference)
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;
class FunderFeatureTest extends TestCase
{
use RefreshDatabase;
/** #test */
public function an_admin_should_be_able_to_view_a_list_of_funders()
{
$this->withoutExceptionHandling();
$this->signIn('admin');
$this->get('/funders')
->assertOk();
}
/** #test */
public function a_user_should_not_be_able_to_view_a_list_of_funders()
{
$this->signIn();
$this->get('/funders')
->assertStatus(403);
}
}
I'm not sure if this is the appropriate way to get this to work, but passing a new instance of a Funder model instead of the class name seemed to do the trick.
Changing $this->authorize('view', Funder::class); to $this->authorize('view', new \App\Funder());
I've got the following factory in Laravel 5.7, when invoking it nothing is being returned:
<?php
use Faker\Generator as Faker;
use Illuminate\Database\Eloquent\Model;
$factory->define(App\Record::class, function (Faker $faker) {
return [
"name" => $faker->name,
];
});
Whereas my model is:
<?php
namespace App;
use App\Product;
use Illuminate\Database\Eloquent\Model;
class Record extends Model
{
protected $table = "records";
protected $fillable = ["name"];
function __construct()
{
parent::__construct();
}
}
And I'm invoking the factory here:
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Foundation\Testing\RefreshDatabase;
use App;
use App\Product;
use App\Record;
use App\User;
class RecordTest extends TestCase
{
use RefreshDatabase;
use WithoutMiddleware;
/** #test */
public function when_record_page_for_existing_record_is_accessed_then_a_product_is_displayed()
{
//$record = factory(App\Record::class)->make();
$record = factory(App\Record::class)->create();
echo "\n\n$record->name\n\n";
}
}
when printing
$record->name
I'm getting nothing, not null, no empty string, just nothing. What seems to be the problem? If I save whatever is generated by the factory into a variable instead of returning it right away I can see that name is being populated, but after returning it nothing happens, it's gone
This piece of code is the problematic part:
function __construct()
{
parent::__construct();
}
You're not passing the attributes to the parent constructor. Eloquent accepts the model's attributes in the constructor, but your overriding constructor doesn't accept them, nor pass them up to the parent.
Change it to this:
function __construct(array $attributes = [])
{
parent::__construct($attributes);
}
BTW, you're overriding Eloquent's constructor, but you're not doing anything in there. Are you sure you actually want to override it?
By default phpunit won't print your echo.
To print it, please use phpunit -v
I have few classes which extends from the abstract class
And Class MenuController Extends from SiteAdminController
I need to call MenuController and receive authenticated user id
<?php
namespace App\Http\Controllers\SiteAdmin;
use App\Http\Categories;
use Illuminate\Http\Request;
use Gate;
use App\Category;
use App\Http\Controllers\MenuController;
use App\Site_categories;
use Auth;
class SiteAdminController extends \App\Http\SiteEntity implements Categories
{
protected $host;
public $user;
public function __construct()
{
parent::__construct();
$this->middleware('auth:admin');
}
protected function menu() {
return $data_nav['menu'] = MenuController::index('admin_categories');
}
Other one extends from SiteAdminCntroller
<?php
namespace App\Http\Controllers\SiteAdmin;
use Illuminate\Http\Request;
use Gate;
use Auth;
use App\Category;
class MenuController extends SiteAdminController
{
public $category_menu;
public $user_categories;
public $user;
public function __construct(Auth $auth)
{
//parent::__construct();
$this->user_categories=$this->CategoriesMenu();
$this->user=$auth::guard('admin')->user()->id;
dd($this->user);
//dd($this->user_categories);
}
I think the constructor in the MenuController run befor the middlware in SiteAdminController
Thats why I have such error
http://prntscr.com/hwfifx
Please Explaine what have I do to see result from me dd() function?
I was trying even to call parent::__construct but it not helping
You are correct that the the code in the constructor runs before the middleware: https://github.com/laravel/framework/issues/15072
The easiest way to get around this is to use the middleware method in the controller:
MenuController
public function __construct()
{
parent::__construct();
$this->middleware(function () {
$this->user_categories = $this->CategoriesMenu();
$this->user = auth()->guard('admin')->user()->id;
});
}
First of all check if the class see another class that must be extended with.
Then try below approach (it s just example):
class ConceptController extends \SiteAdminController {
public function __construct(SiteAdminController $siteAdmin) {
parent::__construct($siteAdmin);
}
}