Skip to content

MockingMethodsCorrectness ​

warning on by default quick-fix

Group: PHPUnit · PhpStorm name: MockingMethodsCorrectnessInspection

Two classes of PHPUnit mock-configuration mistakes inside tests: passing a stub object ($this->returnValue(...), $this->returnCallback(...)) to willReturn() — which then returns the stub object itself instead of running it — and configuring (->method('name')) a method that the mocked class does not have, or that is final and therefore cannot be overridden by the generated double.

Example ​

php
<?php

class Ledger
{
    public function balance() {}
    final public function seal() {}
}

class LedgerTest
{
    public function testDoubles()
    {
        $stub = $this->getMockBuilder(Ledger::class)
            ->setMethods(['virtualTotal'])
            ->getMock();

        $stub->method('balance')->willReturn($this->returnValue(42));
        $stub->method('balance')->willReturn(self::returnCallback('strtoupper'));
        $stub->method('balance')->will($this->returnValue(42));
        $stub->method('balance')->willReturn(42);

        $stub->method('seal')->willReturn(true);
        $stub->method('refund')->willReturn(0);
        $stub->expects($this->once())->method("refund");
        $stub->method('virtualTotal')->willReturn(7);
        $stub->method('BALANCE')->willReturn(1);
        $stub->method($dynamic)->willReturn(1);

        $this->getMockBuilder(Ledger::class)->getMock()->method('seal');
        $this->createMock(Ledger::class)->method('refund');
    }
}
php
<?php

class Ledger
{
    public function balance() {}
    final public function seal() {}
}

class LedgerTest
{
    public function testDoubles()
    {
        $stub = $this->getMockBuilder(Ledger::class)
            ->setMethods(['virtualTotal'])
            ->getMock();

        $stub->method('balance')->will($this->returnValue(42));
        $stub->method('balance')->will(self::returnCallback('strtoupper'));
        $stub->method('balance')->will($this->returnValue(42));
        $stub->method('balance')->willReturn(42);

        $stub->method('seal')->willReturn(true);
        $stub->method('refund')->willReturn(0);
        $stub->expects($this->once())->method("refund");
        $stub->method('virtualTotal')->willReturn(7);
        $stub->method('BALANCE')->willReturn(1);
        $stub->method($dynamic)->willReturn(1);

        $this->getMockBuilder(Ledger::class)->getMock()->method('seal');
        $this->createMock(Ledger::class)->method('refund');
    }
}

Reported:

  • line 17: The stub object is returned as-is here; use '->will(...)'.
  • line 18: The stub object is returned as-is here; use '->will(...)'.
  • line 22: Final methods cannot be mocked.
  • line 23: The mocked class has no such method.
  • line 24: The mocked class has no such method.
  • line 29: Final methods cannot be mocked.

Configure ​

In custos.json:

json
{
  "rules": {
    "MockingMethodsCorrectness": {
      "enabled": false
    }
  }
}

Suppress ​

Before the statement or declaration (or the first statement of the file), either of:

php
// @custos-ignore MockingMethodsCorrectness

/**
 * @noinspection MockingMethodsCorrectnessInspection
 */

Released under the MIT License. Rule catalogue modelled on Php Inspections (EA Extended); independent clean-room implementation.