kaishounachi's avatar

ModelFactory Produces Empty Objects

So I'm trying out this TDD thing because everyone says it's awesome :) So to begin testing one of my Listener classes, I need to mock (stub?) one of my Models (School) using the ModelFactory:


$factory->define('App\Models\School', function ($faker) {
    return [
        'name' => $faker->company,
        'address' => $faker->address,
        'city' => $faker->city,
        'postcode' => $faker->postcode
    ];
});

So in one of my test specs, I make sure that the School model generated by the ModelFactory contains some data:

$this->assertNotNull($school->name, 'School name is NULL!');

This assertion fails.

But an instance of the School model is created without issues:


$this->assertInstanceOf(School::class, $school, 'Generated School is not an instance of App\Models\School!');

This assertion passes.

So I try running the factory function using php artisan tinker and sure enough, the generated model properties are empty.

The problem doesn't seem to lie within the Faker library as I can use it outside the context of Models with no issues (again, using php artisan tinker):


use Faker\Factory as Faker;
$faker = Faker::create();
echo $faker->name;

Results in "Heidi Hamil"


echo $faker->address;

Results in "1386 Cassin Overpass Suite 808, Lebsackside, NM 96669"

So clearly, the problem lies in the factory function saving generated Model's properties.

And yes, I have set the School Model's fillable property to include the name, address, city, postcode properties (as well as a few others)!

My staging server setup:

  • Lumen 5.5
  • Fzaninatto/Faker 1.7
  • PHPUnit 5.7
  • PHP 7.1.18
  • NGINX 1.10.3
  • Ubuntu 16.04

Please help!! I've spent two whole days searching Google and StackOverflow for answers to no avail!

0 likes
2 replies
Snapey's avatar

Do you have $school = factory(App\Models\School::class)->make(); somewhere?

kaishounachi's avatar

Hello Snapey,

Thanks for your reply. Yes, of course, within my test spec, the factory function is called:

/** @test */
  public function test_school_set_to_inactive_in_schools_table()
  {
    // Do not run any Event Listeners
    $this->withoutEvents();

    // Create a fake School and save to the DB
    $school = factory(School::class)->create();

    // Make sure it's a legit App\Models\School instance
    $this->assertInstanceOf(School::class, $school, 'Generated School is not an instance of App\Models\School!');

    // Make sure the generated School object actually has data
    $this->assertNotNull($school->name, 'School name is NULL!');

    // Mock the SchoolController class
    $controller = app()->make(SchoolController::class);

    // Mock the Request class
    $request = \Mockery::mock(Request::class);

    // Call the delete method of the SchoolController
    $result = $controller->delete($request, $school->id);

    // Assert the record has been updated in the DB
    $this->seeInDatabase('schools', [
      'id' => $school->id,
      'active' => 0,
      'weekly_emails' => 0
    ]);
  }

Please or to participate in this conversation.