Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP Unit mocked objects types

What is the correct way of setting a type for mocked objects?

Example code:

/**
 * @dataProvider getTestDataProvider
 * @throws Exception
 */
public function testExampleData(
    Request $request,
    Response $expected,
    SomeClass $someClassMock
): void {
    $result = $someClassMock->getData($request);

    $this->assertEquals($expected, $result);
}

In this example the type of $someClassMock is class SomeClass. Also there is a type called MockObject which is also working properly, but it messes up the autocompletion of functions inside that class.

Which types should I use on these mocked objects? Real object class or MockObject?

like image 400
The50 Avatar asked Jul 20 '26 15:07

The50


1 Answers

What I do to make sure the auto completion works for the mocked class as well as the MockObject, is tell php that it can be either class. This adds the auto complete for both and also makes it quite understandable for anyone reading the code that it is a mock and what object it is mocking.

In your case it would look like this:

/**
 * @dataProvider getTestDataProvider
 * @throws Exception
 */
public function testExampleData(
    Request $request,
    Response $expected,
    SomeClass|MockObject $someClassMock // <-- Change made here
): void {
    $result = $someClassMock->getData($request);

    $this->assertEquals($expected, $result);
}

You will still be passing in the MockObject, but your IDE will not complain about any unknown functions.

EDIT: To make it work with PHP versions before 8, I would suggest something like this (minimal example):

class ExampleTest extends TestCase 
{
    private someClass | MockObject $someClassMock;

    public function setUp(): void
    {
        $this->someClassMock = $this->createMock(SomeClass::Class);
    }

    public function testMe()
    {
        $this->someClassMock->expects($this->once())->method('getData')->willReturn('someStuff');
    }
}


In this scenario the variable $someClassMock is declared as both types and you can use it throughout your test with autocompletion for both of them. This should also work with your data provider although you might have to rewrite it slightly. I didn't include it in my example to keep it simple.

like image 114
Dirk Scholten Avatar answered Jul 22 '26 04:07

Dirk Scholten



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!