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

createMockForIntersectionOfInterfaces() does not automatically register mock object for expectation verification #5563

Closed
rickdenhaan opened this issue Nov 14, 2023 · 1 comment
Assignees
Labels
feature/test-doubles Test Stubs and Mock Objects type/bug Something is broken version/10 Something affects PHPUnit 10

Comments

@rickdenhaan
Copy link

Q A
PHPUnit version 10.4.2
PHP version 8.2.12
Installation Method Composer

Summary

When creating a mock using $this->createMockForIntersectionOfInterfaces(), the created MockObject is not registered in the test case. Because of this, failing expectations are not triggered when the test completes.

Current behavior

createMockForIntersectionOfInterfaces() does not call registerMockObject, which means failing expectations are not flagged as a test failure.

Expected behavior

createMockForIntersectionOfInterfaces() calls registerMockObject just like createMock() does.

How to reproduce

<?php

use PHPUnit\Framework\TestCase;

class Example
{
    public function __construct(private \Stringable $object)
    {
    }

    public function count(): int
    {
        if ($this->object instanceof \Countable) {
            return $this->object->count();
        }

        return 0;
    }
}

class ExampleTest extends TestCase
{
    public function testCount(): void
    {
        $withCountable = $this->createMockForIntersectionOfInterfaces(
            [
                \Stringable::class,
                \Iterator::class,
                \Countable::class,
            ]
        );

        $withoutCountable = $this->createMockForIntersectionOfInterfaces(
            [
                \Stringable::class,
                \Iterator::class,
            ]
        );

        //$this->registerMockObject($withCountable);
        //$this->registerMockObject($withoutCountable);

        $withCountable->expects(self::once())
                      ->method('count');

        $withoutCountable->expects(self::never())
                         ->method(self::anything());

        // lazy copy/pasting: one of these should be withCountable.
        // $withCountable is unused, therefore the count method is never called and the expectation should fail
        (new Example($withoutCountable))->count();
        (new Example($withoutCountable))->count();
    }
}

Running PHPUnit outputs:

PHPUnit 10.4.2 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.2.12


This test did not perform any assertions
Time: 00:00.012, Memory: 8.00 MB

There was 1 risky test:

1) ExampleTest::testCount
This test did not perform any assertions

/path/to/ExampleTest.php:23

OK, but there were issues!
Tests: 1, Assertions: 0, Risky: 1.

Note: PHPUnit exits with exit code 0, meaning if this is the only "failing" test, CI will happily proceed.

Manually registering the mocks (something createMock() does automatically for you) by enabling the registerMockObject lines works as expected:

[...]
        $this->registerMockObject($withCountable);
        $this->registerMockObject($withoutCountable);
[...]
PHPUnit 10.4.2 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.2.12


Expectation failed for method name is "count" when invoked 1 time.
Method was expected to be called 1 time, actually called 0 times.

Time: 00:00.014, Memory: 8.00 MB

There was 1 failure:

1) ExampleTest::testCount
Expectation failed for method name is "count" when invoked 1 time.
Method was expected to be called 1 time, actually called 0 times.

FAILURES!
Tests: 1, Assertions: 1, Failures: 1.

Now the expectation causes a test failure and PHPUnit exits with exit code 1, interrupting CI flow as it should.

@rickdenhaan rickdenhaan added type/bug Something is broken version/10 Something affects PHPUnit 10 labels Nov 14, 2023
@sebastianbergmann sebastianbergmann added the feature/test-doubles Test Stubs and Mock Objects label Nov 14, 2023
@sebastianbergmann sebastianbergmann self-assigned this Nov 14, 2023
@sebastianbergmann sebastianbergmann changed the title Mocks created by createMockForIntersectionOfInterfaces are not registered automatically createMockForIntersectionOfInterfaces() does not automatically register mock object for expectation verification Nov 14, 2023
@rickdenhaan
Copy link
Author

@sebastianbergmann That was quick, thanks for picking it up on such short notice!

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

No branches or pull requests

2 participants