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

Restore the PHPUnit listener #638

Merged
merged 4 commits into from
Oct 27, 2016

Conversation

pschultz
Copy link
Contributor

The listener has been removed in ede1431 because it is called too
late in the test lifecycle. This marks tests incorrectly as risky, if
there are no other assertions in the test.

Simply removing the listener silently breaks existing testsuites for
PHPUnit <5.5.6, which will not complain about missing listeners.

The listener added in this commit will no longer verify mock assertions.
Instead, the listener will mark tests as failed if they don't verify the
mock assertions themselves.

This will surface the change for existing users of the listener and help them
migrate to the trait or base class. Is also serves as an opt-in safefail for
new Mockery users.

This is how it looks in action:

$ bin/phpunit 
PHPUnit 5.3.5 by Sebastian Bergmann and contributors.

...........F

Time: 595 ms, Memory: 43.25MB

There was 1 failure:

1) Classmarkets\Tests\Search\AnalysisRunnerTest::testRunAnalysis
Mockery's expectations have not been verified. Make sure that \Mockery::close() is called at the end of the test. Consider using Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration or extending Mockery\Adapter\Phpunit\MockeryTestCase.

/home/pschultz/src/mockery/library/Mockery/Adapter/Phpunit/TestListener.php:42

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

Fixes #636

The listener has been removed in ede1431 because it is called too
late in the test lifecycle. This marks tests incorrectly as risky, if
there are no other assertions in the test.

Simply removing the listener silently breaks existing testsuites for
PHPUnit <5.5.6, which will not complain about missing listeners.

The listener added in this commit will no longer verify mock assertions.
Instead, the listener will mark tests as failed if they don't verify the
mock assertions themselves.

This will surface the change for existing users of the listener and help them
migrate to the trait or base class. Is also serves as an opt-in safefail for
new Mockery users.

Fixes mockery#636
* @license http://github.com/padraic/mockery/blob/master/LICENSE New BSD License
*/

class Mockery_Adapter_Phpunit_TestListenerTest extends PHPUnit_Framework_TestCase
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me know if you want me to refactor to namespaces. The existing tests didn't have any, so I stuck to that style.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't worry about that :)

// the container is closed already will do.
\Mockery::self();
} catch (\LogicException $_) {
return;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there are is a better way to check this I'm all ears.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it will suffice. I guess you could argue that you might be using Mockery for stubs or spies and post verification isn't required, therefore this would scream at you without justification, but I think we'll worry about that if someone mentions it.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.3%) to 76.309% when pulling 536ed44 on classmarkets:restore-phpunit-listener into 5fa8c52 on padraic:master.

__NAMESPACE__
));
$result = $test->getTestResultObject();
$result->addFailure($test, $e, $time);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably only happen if there are expectations to begin with, right?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I guess my reply to the other question is more relevant here. We can make a choice, throw anyway as a way of warning, or try and be clever and call Mock::close(), work on the result of that call. I don't really mind either way and will go with your judgement.

@davedevelopment
Copy link
Collaborator

@pschultz replied to all comments, I'm happy to merge as is, please make changes regarding my comments if you would like to, otherwise let me know and I'll merge.

@pschultz
Copy link
Contributor Author

Let's merge it as is. I'm updating one of our test suites now and it looks like tests will not fail if Mockery isn't involved.

I'll dig into Mockery's internals later to see if the listener can be improved. I've only ever used mocks, never spies and have to become familiar with the differences.

@pschultz
Copy link
Contributor Author

Actually hold on. There may be a bug. Let me finish migration our test suite. Then I'll be much more confident that this works correctly.

@pschultz
Copy link
Contributor Author

This is definitely broken. There are lots of cases where assertPostConditions isn't called but the listener is, for instance skipped and incomplete tests.

@davedevelopment
Copy link
Collaborator

TLDR for spies, you don't set up expectations on them, they record all interactions and you manually verify against them afterwards, e.g. $spy->shouldHaveReceived("foo")->with("bar")->twice();

@pschultz
Copy link
Contributor Author

Good to go now. I decided to not check unsuccessul tests at all.

As far as I can see, when using only spies it is not strictly necessary to call close(). But it also doesn't hurt so I agree to wait for complaints before getting clever in the listener.

The fact that assertPostConditions isn't called for skipped, incomplete and failing tests is actually a problem. I will create a new issue for that.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.2%) to 76.255% when pulling 1c3a216 on classmarkets:restore-phpunit-listener into 5fa8c52 on padraic:master.


public function testSuccessOnClose()
{
$mock = $this->container->mock('foo');
Copy link
Collaborator

@davedevelopment davedevelopment Oct 27, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using 'foo' here is causing some flaky tests to fail when running the full suite, just calling mock() for these purposes should be fine. Same on lines 56 and 71.

Edit: missed the word "fail"

@pschultz
Copy link
Contributor Author

Let me know if you want to rebase into a single commit.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.2%) to 76.255% when pulling dd0dda9 on classmarkets:restore-phpunit-listener into 5fa8c52 on padraic:master.

@davedevelopment davedevelopment merged commit 8569c87 into mockery:master Oct 27, 2016
@davedevelopment
Copy link
Collaborator

Thanks, great work.

@pschultz pschultz deleted the restore-phpunit-listener branch October 27, 2016 15:40
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

Successfully merging this pull request may close these issues.

Missing TestListener does not fail in most phpunit versions.
3 participants