Larastan: False positive when calling ->refresh() method on Model in a test

Created on 9 Apr 2021  路  7Comments  路  Source: nunomaduro/larastan

  • Larastan Version: 0.7.2
  • --level used: max

Description

The ->refresh() method in a test started failing after updating to the latest Larastan version.

$user = User::seed();
// operations which require a `$user` refresh
$context = Context::create()->withUser($user->refresh());
 ------ ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 
  Line   tests/Unit/Recommendations/ContextTest.php                                                                                                                                    
 ------ ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 
  40     Parameter #1 $user of method App\Domain\Recommendations\Context::withUser() expects App\Domain\Users\User, static(Tests\Unit\Recommendations\ContextTest) given.  

Note that User::seed() in this case is part of a trait that is implemented on the User model and returns static

Laravel code where the issue was found

    /**
     * Reload the current model instance with fresh attributes from the database.
     *
     * @return $this
     */
    public function refresh()
    {
    //...
    }

Most helpful comment

So it's similar to the code I posted above. I moved the trait to another file and tried again, but still can't produce it.

Can you try to PR a failing test for this?

All 7 comments

Hi,

Can you add \PHPStan\dumpType($user) after $user = User::seed(); part and tell me what is the output?

I dumped $user on line 40 ~en~ and $user->refresh() on line 41

 ------ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
  Line   tests/Unit/Recommendations/ContextTest.php                                                                                                                                   
 ------ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
  40     Dumped type: static(App\Domain\Users\User)                                                                                                                             
  41     Dumped type: $this(Tests\Unit\Recommendations\ContextTest)                                                                                                                   
  43     Parameter #1 $user of method App\Domain\Recommendations\Context::withUser() expects App\Domain\Users\User, $this(Tests\Unit\Recommendations\ContextTest) given.  
 ------ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 

en

For English readers: it means _and_

I tried to reproduce this with the following

$user = User::seed();
// operations which require a `$user` refresh
$context = Context::create()->withUser($user->refresh());

class User extends \Illuminate\Database\Eloquent\Model {
    use Seed;
}

class Context extends \Illuminate\Database\Eloquent\Model {
    public function withUser(User $user): Context
    {
        return $this;
    }
}

trait Seed {
    /** @return static */
    public static function seed() {
        $instance = new static;

        return $instance;
    }
}

and I don't get the error you get. Here is also similar thing: https://phpstan.org/r/6f7caf44-a99d-4840-9b23-2bc5ffe65469 or https://phpstan.org/r/08aaf440-f206-4f66-90b7-275b030dc27f

Can you share the signature of the seed method? And how you instantiate the class in the trait?

This might not be related to Larastan. Cause with Larastan 0.7.2 we require minimum PHPStan 0.1.283 which has some new changes how the static keyword is resolved.

Sorry, I should have provided that part from the start. The seed is essentially a wrapper around HasFactory:

    /**
     * @return static
     */
    public static function seed(array $attributes = []): self
    {
        return static::factory()->create($attributes);
    }

So it's similar to the code I posted above. I moved the trait to another file and tried again, but still can't produce it.

Can you try to PR a failing test for this?

Hi,

I'm gonna close this issue because there is no new activity in 2 months. If you can send a failing test case in a PR, I'd take a look 馃憤馃徑

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Gummibeer picture Gummibeer  路  3Comments

jdrieghe picture jdrieghe  路  4Comments

iNviNho picture iNviNho  路  3Comments

gitetsu picture gitetsu  路  4Comments

JeroenVanOort picture JeroenVanOort  路  3Comments