Trying to get Auth up and running on a project and Im running into trouble making model factories for testing. Im getting the following error when trying to create a model with a factory: Unable to locate factory with name [default]
Heres my test:
<?php
namespace App\Tests\Integration;
use App\Tests\TestCase;
class AuthTest extends TestCase
{
/**
* @test
*/
public function it_logs_in_user()
{
factory(App\User::class)->create();
}
}
After a bit of debugging, I found that in my test, App\User::class was returning '\Tests\Integration\App\User' instead of 'App\User'. Using '\App\User' solved the problem.
<?php
namespace App\Tests\Integration;
use App\Tests\TestCase;
class AuthTest extends TestCase
{
/**
* @test
*/
public function it_logs_in_user()
{
factory(\App\User::class)->create();
}
}
Just in case, someone else reads this, who uses setUp() method to initialize factory models.
My problem was actually forgetting to call parent::setUp(). I overrode setUp() method on my test and initialized all factories there.
public function setUp()
{
parent::setUp(); // I forgot this one
$this->user = factory('App\User')->create();
$this->thread = factory('App\Thread')->create();
$this->reply = factory('App\Reply')->create([
'user_id' => $this->user->id
]);
}
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\DatabaseMigrations;
class ThreadsTest extends TestCase
{
use DatabaseMigrations;
private $thread;
/**
* @test
*
* A user can view all threads.
*
* @return void
*/
public function a_user_can_view_all_threads()
{
$this->thread = factory('App\Models\Thread')->create();
$response = $this->get('/threads');
$response->assertSee($this->thread->title);
}
/**
* @test
*
* A user can read a single thread.
*
* @return void
*/
public function a_user_can_read_a_single_thread()
{
$this->thread = factory('App\Models\Thread')->create();
$response = $this->get('/threads/' . $this->thread->id);
$response->assertSee($this->thread->title);
}
}
The code above works perfectly, but if I instead initialize $thread in a constructor:
public function __construct() {
$this->thread = factory('App\Models\Thread')->create();
}
phpunit throws PHP Fatal error: Uncaught InvalidArgumentException: Unable to locate factory with name [default] [App\Models\Thread]. What I am trying to do is using the same fake thread for both tests, instead of generating a fake thread for each test. Any suggestion?
@Kenshirou You can't overload the constructor of a unit test like that. 1. you never call the parent constructor that way (relevant for PHPUnit 6 only) and 2. it's not recommended, since their is a dedicated setUp method for that.
You have to overload the setUp method instead. For ex.:
protected function setUp() {
parent::setUp();
$this->thread = factory('App\Models\Thread')->create();
}
Is it expected that when we create a unit test we have to change the TestCase for the correct one? I also created a test and out of the box comes as PHPUnit\Framework\TestCase; instead of \Tests\TestCase
I figure out that when you create unit tests throught "artisan make:test --unit" the created test class will extends "PHPUnit\Framework\TestCase;" if you need some database refresh this test should be created as a feature test, which extends the "TestCase" base clase provided by laravel
Hey Guys,
use following code to fix Unable to locate factory for [App\FactoryName] error:
<?php
use App\Article;
use Tests\TestCase;
class ArticleTest extends TestCase
{
/** @test */
public function it_fetches_trending_article()
{
// Given
factory(Article::class, 2)->create();
...
}
}