Skip to content

PHPUnit setup methods should be treated equally to constructors #107

@morozov

Description

@morozov

PHPUnit executes setUp() and other @before methods on each test run, so with regards to the test (test*() and @test) methods they behave more or less like a constructor.

When analyzing test classes, Psalm and the PHPUnit plugin report the properties initialized in setup methods as not initialized in constructor.

$ composer show | grep psalm
psalm/plugin-phpunit                           0.15.1    Psalm plugin for PHPUnit
vimeo/psalm                                    4.5.2     A static analysis tool for find...
<?php

namespace Tests;

use PHPUnit\Framework\TestCase;
use stdClass;

class ObjectTest extends TestCase
{
    /** @var stdClass */
    private $object;

    protected function setUp(): void
    {
        $this->object = new stdClass();
    }

    public function testObject(): void
    {
        self::assertIsNotNull($this->object);
    }
}
$ psalm tests/ObjectTest.php

ERROR: PropertyNotSetInConstructor - tests/ObjectTest.php:11:13 - PropertyTests\ObjectTest::$object is not defined in constructor of Tests\ObjectTest and in any private or final methods called in the constructor (see https://psalm.dev/074)
    private $object;

While it's technically true, it's irrelevant for the test cases. By the time when the test method is invoked, the property will be initialized.

It is possible to rework such tests to initialize the object explicitly for each test method but this is less convenient, more verbose and in fact invalidates the PHPUnit setup approach.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions