Phpstan: Call to deprecated method getMockForAbstractClass()

Created on 27 June 2024, 3 days ago

getMockForAbstractClass() is deprecated in PHPUnit 10 and removed from PHPUnit 12.

📌 Task
Status

Needs work

Version

4.0

Component

Tests

Created by

🇺🇸United States TR Cascadia

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @TR
  • 🇺🇸United States TR Cascadia

    I'm not at all sure about this because PHPUnit didn't replace this method with anything, but here's a try at it.

  • 🇮🇳India abhiyanshu_rawat

    Absolutely correct @tr,
    Since getMockForAbstractClass() has been removed without a direct replacement method within PHPUnit itself, the recommended approach now is to use the getMockBuilder() method directly to create a mock object for an abstract class.

    i.e..,

    use PHPUnit\Framework\TestCase;
    
    abstract class AbstractClass {
        abstract public function method1();
        abstract public function method2();
    }
    
    class MyTest extends TestCase {
        public function testSomething() {
            $mock = $this->getMockBuilder(AbstractClass::class)
                         ->getMock();
    
            // Define mock behavior or expectations
            $mock->expects($this->any())
                 ->method('method1')
                 ->willReturn('foo');
    
            // Assertions or test logic with $mock
            $this->assertEquals('foo', $mock->method1());
        }
    }
    
  • Status changed to Needs work 3 days ago
  • 🇺🇸United States TR Cascadia

    Yeah, that's what I did. But it's not quite right - the tests failed. Maybe you can take a look and see what I missed?

  • 🇮🇳India abhiyanshu_rawat

    Sure, I revisited Merge Request !42 and created a patch for it.
    Included some missing code, Hope it works. Thanks.

  • 🇺🇸United States TR Cascadia

    @abhiyanshu
    So I understand your change to use $methods instead of [$methods] - that was my error, and I fixed it in the MR.

    But the other changes I don't think are correct. For example:

         $rules_action_base = $this->getMockBuilder(RulesActionBase::class)
           ->setConstructorArgs([[], '', ['label' => 'something']])
    +      ->onlyMethods(['getPluginLabel'])
           ->getMock();
    +
    +    $rules_action_base
    +      ->expects($this->once())
    +      ->method('getPluginLabel')
    +      ->willReturn('something');
    +
         $this->assertEquals('something', $rules_action_base->summary());

    We were formerly using getMockForAbstractClass() here ... but I changed it to getMockBuilder() for this issue.
    Regardless, the point is that we have an abstract base class with some concrete methods, and we want to test one of those concrete methods here. So with getMockForAbstractClass() what happened was it returned a mock for the abstract class where the actual concrete methods worked and the abstract methods were mocked.

    What you've done with this change is to mock getPluginLabel() and specify what it should return, then test that it does return that.

    That's not what we want, because of course that will work.

    We want to test that the actual concrete getPluginLabel() (not a mock of that method), will return the correct value. That's what used to happen with getMockForAbstractClass()

Production build 0.69.0 2024