Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel 5 Unit Test - Call to a member function connection() on null

Tags:

I tried creating a unit test for the relationships between my User and Shop models, however when I run vendor\\bin\\phpunit this error(s) are thrown, I have no idea about this since I'm a newbie in unit testing. I tried to run my code on my controller to see if the relationship actually works, and fortunately it is working as expected, but not when run in phpunit. What have I done wrong for this phpunit not to work with Models?

Fatal error: Uncaught Error: Call to a member function connection() on null in E:\projects\try\vendor\laravel\framework\src\Illuminate\Database\Eloquent\Model.php:1013

Stack trace: E:\projects\try\vendor\laravel\framework\src\Illuminate\Database\Eloquent\Model.php(979): Illuminate\Database\Eloquent\Model::resolveConnection(NULL)

This is my UserTest.php

<?php  namespace Tests\Unit;  use Tests\TestCase; use Illuminate\Foundation\Testing\DatabaseMigrations; use Illuminate\Foundation\Testing\DatabaseTransactions;  use App\User; use App\Shop;  class UserTest extends TestCase {      protected $user, $shop;      function __construct()     {         $this->setUp();     }          function setUp()     {         $user = new User([             'id' => 1,             'first_name' => 'John',             'last_name' => 'Doe',             'email' => '[email protected]',             'password' => 'secret',             'facebook_id' => null,             'type' => 'customer',             'confirmation_code' => null,             'newsletter_subscription' => 0,             'last_online' => null,             'telephone' => null,             'mobile' => null,             'social_security_id' => null,             'address_1' => null,             'address_2' => null,             'city' => null,             'zip_code' => null,             'signed_agreement' => 0,             'is_email_confirmed' => 0         ]);          $user = User::find(1);         $shop = new Shop([             'id' => 1,             'user_id' => $user->id,             'name' => 'PureFoods Hotdog2',             'description' => 'Something that describes this shop',             'url' => null,             'currency' => 'USD'         ]);         $user->shops()->save($shop);          $shop = new Shop([             'id' => 2,             'user_id' => $user->id,             'name' => 'PureFoods Hotdog',             'description' => 'Something that describes this shop',             'url' => null,             'currency' => 'USD'         ]);          $user->shops()->save($shop);          $this->user = $user;      }      /** @test */     public function a_user_has_an_id(){         $user =  User::find(1);         $this->assertEquals(1, $user->id);     }      /** @test */     public function a_user_has_a_first_name()     {         $this->assertEquals("John", $this->user->first_name);     }      /** @test */     public function a_user_can_own_multiple_shops()     {         $shops = User::find(1)->shops()->get();         var_dump($this->shops);         $this->assertCount(2, $shops);     } } 

It seems, this error is caused by this line of code: $user->shops()->save($shop); - this code actually works when run in my sample routes or Controller but is throwing errors when run in phpunit

User.php

<?php  namespace App;  use Illuminate\Notifications\Notifiable; use Illuminate\Foundation\Auth\User as Authenticatable;  class User extends Authenticatable {     use Notifiable;      protected $guarded = [ 'id' ];     protected $table = "users";         /**      * The attributes that should be hidden for arrays.      *      * @var array      */     protected $hidden = [         'password', 'remember_token',     ];       /**      * returns the Shops that this user owned      */     public function shops()     {         return $this->hasMany('App\Shop');     } } 

Shop.php

<?php  namespace App;  use Illuminate\Database\Eloquent\Model;  class Shop extends Model {     protected $guarded = [ 'id' ];     protected $table = "shops";      /**      * returns the Owner of this Shop      */     public function owner()     {         return $this->belongsTo('App\User');     } } 

Any help will be very much appreciated. Thanks!

like image 937
Dexter Bengil Avatar asked Feb 28 '17 15:02

Dexter Bengil


2 Answers

One more reason

check if the test class is extending use Tests\TestCase; rather then use PHPUnit\Framework\TestCase;

Laravel ships with the later, but Tests\TestCase class take care of setting up the application, otherwise models wont be able to communicate with the database if they are extending PHPunit\Framework\TestCase.

like image 110
f_i Avatar answered Sep 20 '22 10:09

f_i


First of all, setUp() is called before every test, so you shouldn't call it from within the constructor

Second of all, you should call the parent::setUp() in your setUp() to initialize the app instance.

like image 45
jakub wrona Avatar answered Sep 20 '22 10:09

jakub wrona