Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PHPUnit genrates invalid mock code when false is in a union e.g. false|int #4735

Closed
olvlvl opened this issue Jul 18, 2021 · 4 comments
Closed
Assignees
Labels
feature/test-doubles Stubs and Mock Objects type/bug Something is broken

Comments

@olvlvl
Copy link

olvlvl commented Jul 18, 2021

Q A
PHPUnit version 9.5.6
PHP version 8.0.8
Installation Method Composer

Summary

PHPUnit generates invalid mock code when the type false is used in a union e.g. false|int.

Current behavior

The following code is generated:

declare(strict_types=1);

class false|int
{
}

class Mock_false|int_189b4275 extends false|int implements PHPUnit\Framework\MockObject\MockObject
{
    use \PHPUnit\Framework\MockObject\Api;
    use \PHPUnit\Framework\MockObject\Method;
    use \PHPUnit\Framework\MockObject\MockedCloneMethod;
}

How to reproduce

Here's an example class:

<?php

namespace Dummy;

class Sample
{
    public function doSomething(): false|int
    {
        return false;
    }
}

Here's an example test:

<?php

namespace Tests\Dummy;

use Dummy\Sample;
use PHPUnit\Framework\TestCase;

class SampleTest extends TestCase
{
    public function testExec()
    {
        $mock = $this->createMock(Sample::class);

        $mock->doSomething("hello");
    }
}

Expected behavior

The code for the mock is generated correctly.

Note

Using bool|int fixes the issue, but it changes the meaning of the function, because it will never return true. Besides, false|int is a valid unit type.

@olvlvl olvlvl added the type/bug Something is broken label Jul 18, 2021
@sebastianbergmann sebastianbergmann added the feature/test-doubles Stubs and Mock Objects label Jul 19, 2021
@sebastianbergmann sebastianbergmann self-assigned this Jul 19, 2021
@sebastianbergmann
Copy link
Owner

Thank you for reporting this. This only happens when you create a test double and then do not configure a return value for a method that returns *|false.

@olvlvl
Copy link
Author

olvlvl commented Jul 19, 2021

The following code works indeed:

class SampleTest extends TestCase
{
    public function testExec()
    {
        $mock = $this->createMock(Sample::class);
        $mock->method('doSomething')->willReturn(false, 123);

        $this->assertFalse($mock->doSomething("hello"));
        $this->assertEquals(123, $mock->doSomething("hello"));
    }
}

But how's one supposed to know? Could PHPunit display an error message instead of generating invalid code?

@sebastianbergmann
Copy link
Owner

I do not understand what you are asking. The issue you reported has been fixed in fe06cbe.

@olvlvl
Copy link
Author

olvlvl commented Jul 19, 2021

Sorry, I read your message and I missed this bit:

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature/test-doubles Stubs and Mock Objects type/bug Something is broken
Projects
None yet
Development

No branches or pull requests

2 participants