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

Strict mocking #3158

Open
index0h opened this issue Jun 4, 2018 · 6 comments
Open

Strict mocking #3158

index0h opened this issue Jun 4, 2018 · 6 comments
Labels
feature/test-doubles Stubs and Mock Objects type/enhancement A new idea that should be implemented

Comments

@index0h
Copy link

index0h commented Jun 4, 2018

Q A
PHPUnit version 7.0.2
PHP version 7.2.6
Installation Method Composer

Hi, by default phpunit mock object allows you to call any methods: mocked and real.
You should declare a lot of "never" expectations in test cases for complete check your code.
When your covered code is changing, for example added new call of depended mock, tests not fail.
This behavior is error source.

Example:

class Dependency
{
    public function first() {}
    public function second() {}
}

class Testable
{
    /** @var Dependency */
    private $dependency;

    public function __construct(Dependency $dependency)
    {
        $this->dependency = $dependency;
    }

    public function run(bool $runFirst): void
    {
        if ($runFirst) {
            $this->dependency->first();
        } else { // Added just now
            $this->dependency->second();
        }
    }
}

class TestableTest extends TestCase
{
    // Developer forgot to mock Dependency::second method, but test not fail
    public function testRunPositive(): void
    {
        /** @var Dependency|MockObject $dependency */
        $dependency = $this->createMock(Dependency::class);

        $dependency
            ->expects($this->once())
            ->method('first');

        (new Testable($dependency))->run(true);
    }

    // Developer forgot to mock Dependency::second method, but test not fail
    public function testRunNegative(): void
    {
        /** @var Dependency|MockObject $dependency */
        $dependency = $this->createMock(Dependency::class);

        $dependency
            ->expects($this->never())
            ->method('first');

        (new Testable($dependency))->run(false);
    }
}

I'm trying to create constraint, which denies calling not mocked methods.
Is there way to get method name matchers without reflection, or call InvocationMocker::matches without invocation of other constraints?

I also tried to override InvocationMocker and set it to mockObject by reflection but it's dirty hack((

Could you suggest some other way for my case?

@epdenouden
Copy link
Contributor

@index0h Thank you for the bug report! As it relates to dependencies also, I will have a look if it relates to #3092.

@sebastianbergmann
Copy link
Owner

I agree with @index0h, that there should be an API, for instance createStrictMock() and createStrictStub() (see #3120), that allows creating test doubles that are, by default, closer to what Prophecy does.

@sebastianbergmann sebastianbergmann added type/enhancement A new idea that should be implemented feature/test-doubles Stubs and Mock Objects labels Jun 4, 2018
@sebastianbergmann
Copy link
Owner

@epdenouden I do not think that this has anything to do with @depends and/or your recent improvements to how PHPUnit executes tests.

@epdenouden
Copy link
Contributor

@sebastianbergmann Alright, I will continue on the other PR then. Lemme know if anything comes up and I'll take a look tonight

@index0h
Copy link
Author

index0h commented Jan 8, 2019

Any news here?

@stale stale bot added the stale label Jul 2, 2019
Repository owner deleted a comment from stale bot Jul 2, 2019
@Chekote
Copy link

Chekote commented Nov 23, 2020

I'm also curious about the status of this. Has there been any developments?

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/enhancement A new idea that should be implemented
Projects
None yet
Development

No branches or pull requests

4 participants