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

[5.5+] Mockery assertions not counted and tests marked as risky #25703

Closed
dmason30 opened this issue Sep 19, 2018 · 9 comments
Closed

[5.5+] Mockery assertions not counted and tests marked as risky #25703

dmason30 opened this issue Sep 19, 2018 · 9 comments

Comments

@dmason30
Copy link
Contributor

dmason30 commented Sep 19, 2018

  • Laravel Version: 5.5.43 (Could be an issue in 5.6/5.7)
  • PHP Version: 7.1
  • PHPUnit: 6.5.13

Description:

In #20606 there was an attempt to fix this issue by adding the below code in the tearDown method:

            if ($container = Mockery::getContainer()) {
                $this->addToAssertionCount($container->mockery_getExpectationCount());
            }

The issue here is in PHPUnit 6.* the Mark test as risky check was moved to before the tearDown function. So the change made in #20606 no longer seems to have the desired effect.

A similar issue was discussed in sebastianbergmann/phpunit#2758 and it appears that the above code should be handled in assertPostConditions.

Mockery does provide a Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration trait that handles this.

I am not sure if this would be compatible with the TestCase provided in laravel. I have managed to put it in my own TestCase extending Laravel's class and it seems to work correctly.

Steps to replicate

Create a test that only contains a Mockery assertion/expectation and PHPUnit 6 thinks its risky.

Below is a very crude example that replicates the issue. It is not really testing anything but it is the simplest example I came up with.

Foo.php

namespace App;

class Foo
{
    public function bar()
    {
        if ($this->baz()) {
            return true;
        }

        return false;
    }

    public function baz()
    {
        return false;
    }
}

FooTest.php

namespace Tests\Unit;

use App\Foo;
use Tests\TestCase;

class FooTest extends TestCase
{
    public function test_foo()
    {
        $m = \Mockery::mock(Foo::class)->makePartial();
        app()->instance(Foo::class, $m);

        $m->shouldReceive('baz')
            ->once()
            ->withNoArgs()
            ->andReturn(true);

        app(Foo::class)->bar();
    }
}
@staudenmeir
Copy link
Contributor

Please post an example test.

@dmason30
Copy link
Contributor Author

@staudenmeir I have added it to the op

@staudenmeir
Copy link
Contributor

This test runs successfully on my machine. What's your exact PHPUnit version?

@dmason30
Copy link
Contributor Author

dmason30 commented Sep 19, 2018

@staudenmeir

PHPUnit: 6.5.13
Laravel: 5.5.43

phpunit.xml

<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
         backupStaticAttributes="false"
         bootstrap="vendor/autoload.php"
         colors="true"
         convertErrorsToExceptions="true"
         convertNoticesToExceptions="true"
         convertWarningsToExceptions="true"
         processIsolation="false"
         stopOnFailure="false">
    <testsuites>
        <testsuite name="Integration Tests">
            <directory suffix="Test.php">./tests/Integration</directory>
        </testsuite>
        <testsuite name="Unit Tests">
            <directory suffix="Test.php">./tests/Unit</directory>
        </testsuite>
    </testsuites>
    <filter>
        <whitelist processUncoveredFilesFromWhitelist="true">
            <directory suffix=".php">./app</directory>
        </whitelist>
    </filter>
    <php>
        <env name="APP_ENV" value="testing"/>
        <env name="APP_DEBUG" value="false"/>
        <env name="API_DEBUG" value="false"/>
        <env name="DB_CONNECTION" value="mysql_testing"/>
        <env name="CACHE_DRIVER" value="array"/>
        <env name="SESSION_DRIVER" value="array"/>
        <env name="QUEUE_DRIVER" value="sync"/>
        <env name="MAIL_DRIVER" value="log"/>
    </php>
</phpunit>

@staudenmeir
Copy link
Contributor

I'm using the same versions. Can you reproduce the issue on a fresh Laravel installation?

@dmason30
Copy link
Contributor Author

@staudenmeir I'll try that tomorrow, seemed pretty cut and dry to replicate, thanks for the help so far...

@laurencei
Copy link
Contributor

I've seen this before - and the problem I had was I was overriding either the tearDown() or the setUp() in one of my main test files (cant remember which), but I forgot to call the parent:: version during that, which caused the issue above.

Given we cant replicate on a fresh install of Laravel, I'm going to close this issue.

If @dmason30 you can provide steps to replicate on a fresh install - ping me here with the steps and I'll reopen the ticket.

@dmason30
Copy link
Contributor Author

dmason30 commented Sep 20, 2018

@laurencei I will look at this soon, however just as an FYI, Mockery
was upgraded to v1 in Laravel 5.5 and in the Mockery Upgrading docs it states:

http://docs.mockery.io/en/latest/getting_started/upgrading.html#upgrading-to-1-0-0

As of 1.0.0, PHPUnit test cases where we want to use Mockery, should either use the \Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration trait, or extend the \Mockery\Adapter\Phpunit\MockeryTestCase test case. This will in turn call the \Mockery::close() method for us.

However the trait or class does more than just the close it handles the above assertion count issue and coverage.

http://docs.mockery.io/en/latest/reference/phpunit_integration.html#phpunit-integration

To integrate Mockery into PHPUnit and avoid having to call the close method and have Mockery remove itself from code coverage reports,
...
Extending MockeryTestCase or using the MockeryPHPUnitIntegration trait is the recommended way of integrating Mockery with PHPUnit, since Mockery 1.0.0.

@dmason30
Copy link
Contributor Author

@laurencei Turns out it was laravel/browser-kit-testing was still on v2 which meant that the above code was missing. 😳 My bad. Sorry.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants