phpunit, laravel: Cannot use "parent" when current class scope has no parent
Asked Answered
R

2

9

I'm using PHPUnit 6.5.13 and Laravel 5.5 on PHP 7.4. I recently upgraded from PHP 7.2 to 7.4. and it seems like that triggered the error.

In my test I use $this->expectsEvents in order to test that an event is fired. The test class looks a little like this:

namespace Tests\Feature;
use Tests\TestCase;
use App\Events\OrderReSent;

class MyEventTest extends TestCase {
    /** @test */
    public function authenticated_client_can_resend()
    {
        $this->expectsEvents(OrderReSent::class); // there is some more code but this is the line that returns the error
    }
}

OrderReSent looks like this (I've tried commenting out broadcastOn and remove InteractsWithSockets use, no change in result):

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;

class OrderReSent
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $invoiceId;

    public function __construct($invoiceId)
    {
        $this->invoiceId = $invoiceId;
    }

    public function broadcastOn()
    {
        return new PrivateChannel('channel-name');
    }
}

The only place I see parent::__construct being called is in Illuminate\Broadcasting\PrivateChannel, which extends Illuminate\Broadcasting\Channel (and it is a child class, so I don't understand why it would throw this error):

namespace Illuminate\Broadcasting;

class PrivateChannel extends Channel
{
    /**
     * Create a new channel instance.
     *
     * @param  string  $name
     * @return void
     */
    public function __construct($name)
    {
        parent::__construct('private-'.$name);
    }
}

The stacktrace looks like this and makes me believe Mockery is the culprit:

1) Tests\Feature\MyEventTest::authenticated_client_can_resend
ErrorException: Cannot use "parent" when current class scope has no parent

/project-root/vendor/mockery/mockery/library/Mockery/Loader/EvalLoader.php:16
/project-root/vendor/mockery/mockery/library/Mockery/Loader/EvalLoader.php:16
/project-root/vendor/mockery/mockery/library/Mockery/Container.php:219
/project-root/vendor/mockery/mockery/library/Mockery.php:89
/project-root/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MocksApplicationServices.php:99
/project-root/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MocksApplicationServices.php:54
/project-root/tests/Feature/MyEventTest.php:29
Romeyn answered 16/12, 2019 at 13:59 Comment(0)
J
11

I had same issue - it turned out that mockery/mockery was set to version 0.9 in my composer.json. Upgrading mockery/mockery to version 1.3 solved the problem for me.

Related composer.json fragment:

        "mockery/mockery": "~1.3.0",
        "phpunit/phpunit": "~8.0",

Try setting same versions and run composer update

Jinnyjinrikisha answered 2/2, 2020 at 9:53 Comment(3)
I was thinking of this, but we are currently on a few different PHP-versions, namely 7.0, 7.2 and some 7.3. I was hoping to get us up to 7.4, but a little bit worried about backwards compatibility as we aren't ready to upgrade our 7.0-stations quite yet. I'll try and get back to you with the results :pRomeyn
Tests run fine with PHP 7.2, 7.3 and 7.4. This seems to have solved it. Thank you very much!Romeyn
@Robert Trzebiński - This helped to solve my problem. Thanks! Do you know exactly what was updated in mockery to resolve this issue?Telescopy
S
1

The likely culprit is due to new syntax requirements for setUp and tearDown. Source

It can be caused by a missing return type, which is void.

For example, change this:

public function setUp()
{
    parent::setUp();
}

public function tearDown()
{
    parent::tearDown();

}

to this:

public function setUp() : void
{
    parent::setUp();
}

public function tearDown() : void
{
    parent::tearDown();

}

Note: I found this question looking for the error message in a unit test, and oddly enough it was related to m::close(), so I'm describing a different problem than the original question, but my answer will be relevant.

Secondclass answered 3/6, 2020 at 5:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.