mayen222's avatar

Test throws BadMethodCallException : Method Illuminate\Database\Eloquent\Collection::

Hi, I'm doing a test that adds a profile to a user. When I run it with Tinker works fine, it saves the profile and can return it. But when I do it on the test (I'm trying to practice TDD) it says BadMethodCallException: Method Illuminate\Database\Eloquent\Collection::profile does not exist. It fails on $user->profile()->save($profile); But both models have the relations assigned...in fact, they work on Tinker. So I don't know what happens. Can anyone guess what is it and explain to me? Thank you!

Test class

<?php

namespace Tests\Integration;

use App\User;
use App\Entities\userProfile\Profile;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

/**
 * Class UserProfileTest
 * @package Tests\Unit\userProfile
 */
class UserProfileTest extends TestCase
{
    use RefreshDatabase;

    /**
     * A basic test example.
     * @test
     * @return void
     */
    public function it_adds_Profile_to_user()
    {
        $user = factory(User::class, 1)->create();
        $profile = new Profile(
            [
            'days'=> 5,
            'portion'=> 2,
            'max_difficulty'=> 5,
            ]
        );

        $user->profile()->save($profile);

        $this->assertEquals('5', $user->profile->days);
    }
}

Profile class

<?php

namespace App\Entities\userProfile;

use Illuminate\Database\Eloquent\Model;

class Profile extends Model
{
    /**
     * Fillable fields for a Profile
     *
     * @var array
     */
    protected $fillable = [

        'days','max_difficulty','portion'
    ];

    /**
     * A profile belongs to a user
     *
     * @return mixed
     */
    public function user()
    {
        return $this->belongsTo('App\User');
    }


}

User class

<?php

namespace App;

use App\Entities\userProfile\Profile;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Passport\HasApiTokens;

class User extends Authenticatable
{
    use HasApitokens, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    public function profile()
    {
        return $this->hasOne('App\Entities\userProfile\Profile');
    }
}

Ah, I'm using Laravel 6 but I guess that's not the problem...

0 likes
2 replies
Sti3bas's avatar
Sti3bas
Best Answer
Level 53

@mayen222 $user = factory(User::class, 1)->create(); returns a Collection, because you're passing a number of records. Change it to $user = factory(User::class)->create();.

mayen222's avatar

Thanks a lot, @sti3bas! That was it! I'll try to be more careful with the return types in the future :S Again, thanks for the help :D

1 like

Please or to participate in this conversation.