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

getMockBuilder() should also work with non-existent classes #28

Open
wants to merge 1 commit into
base: 1.1.x
Choose a base branch
from

Conversation

Majkl578
Copy link
Contributor

@Majkl578 Majkl578 commented Aug 18, 2018

TestCase::getMockBuilder() can be used with undefined classes as well. In this case, the mock system creates dummy empty class of the given name.

This is used in Doctrine on some places, i.e. for testing event listeners that are based on naming, not interface.

Without this patch, we were getting the following errors:

 ------ ---------------------------------------------------------------------------- 
  Line   tests/Doctrine/Tests/DBAL/ConnectionTest.php                                
 ------ ---------------------------------------------------------------------------- 
  144    Call to method expects() on an unknown class ConnectDispatchEventListener.  
 ------ ---------------------------------------------------------------------------- 

 ------ ------------------------------------------------------------------------------------- 
  Line   tests/Doctrine/Tests/DBAL/Functional/Schema/SchemaManagerFunctionalTestCase.php      
 ------ ------------------------------------------------------------------------------------- 
  349    Call to method expects() on an unknown class ListTableColumnsDispatchEventListener.  
  377    Call to method expects() on an unknown class ListTableIndexesDispatchEventListener.  
 ------ ------------------------------------------------------------------------------------- 

 ------ ------------------------------------------------------------------------------------- 
  Line   tests/Doctrine/Tests/DBAL/Platforms/AbstractPlatformTestCase.php                     
 ------ ------------------------------------------------------------------------------------- 
  372    Call to method expects() on an unknown class GetCreateTableSqlDispatchEvenListener.  
  375    Call to method expects() on an unknown class GetCreateTableSqlDispatchEvenListener.  
  396    Call to method expects() on an unknown class GetDropTableSqlDispatchEventListener.   
  421    Call to method expects() on an unknown class GetAlterTableSqlDispatchEvenListener.   
  424    Call to method expects() on an unknown class GetAlterTableSqlDispatchEvenListener.   
  427    Call to method expects() on an unknown class GetAlterTableSqlDispatchEvenListener.   
  430    Call to method expects() on an unknown class GetAlterTableSqlDispatchEvenListener.   
  433    Call to method expects() on an unknown class GetAlterTableSqlDispatchEvenListener.   
 ------ -------------------------------------------------------------------------------------

No tests for Type\PHPUnit - how to add some?

@Majkl578
Copy link
Contributor Author

@lookyman @ondrejmirtes Can you please review this as a bugfix for 0.10.x? Thanks.

@ondrejmirtes
Copy link
Member

Hi, what about createMock? That one needs the same fix probably: https://github.com/phpstan/phpstan-phpunit/blob/master/src/Type/PHPUnit/CreateMockDynamicReturnTypeExtension.php

@Majkl578
Copy link
Contributor Author

According to this comment from Sebastian Bergmann, non-existent classes cannot be used with createMock() API, but can be used with Mock Builder API:

Classes that do not exist cannot be doubled using the new createMock() API.

and

Classes that do not exist can still be doubled using the Mock Builder API.

It's 2 years old commit though, it may've changed.

@ondrejmirtes
Copy link
Member

Can you verify that with a quick test?

@Majkl578
Copy link
Contributor Author

Majkl578 commented Aug 20, 2018

Seems to still be valid:

<?php

class NonExistentTest extends PHPUnit\Framework\TestCase
{
    public function testCreateMock()
    {
        $mock = $this->createMock('NonExistent');
        self::assertInstanceOf(PHPUnit\Framework\MockObject\MockObject::class, $mock);
    }

    public function testGetMockBuilder()
    {
        $mock = $this->getMockBuilder('NonExistent')->getMock();
        self::assertInstanceOf(PHPUnit\Framework\MockObject\MockObject::class, $mock);
    }
}
$ vendor/bin/phpunit NonExistentTest.php
PHPUnit 7.3.1 by Sebastian Bergmann and contributors.

W.                                                                  2 / 2 (100%)

Time: 56 ms, Memory: 4.00MB

There was 1 warning:

1) NonExistentTest::testCreateMock
Cannot stub or mock class or interface "NonExistent" which does not exist

WARNINGS!
Tests: 2, Assertions: 1, Warnings: 1.

@Majkl578
Copy link
Contributor Author

This is because it's explicitly disallowed in createMock():
https://github.com/sebastianbergmann/phpunit/blob/7.3.1/src/Framework/TestCase.php#L1311

@ondrejmirtes
Copy link
Member

Cool. Maybe we should modify https://github.com/phpstan/phpstan-phpunit/blob/master/src/Type/PHPUnit/MockBuilderDynamicReturnTypeExtension.php too to return a little bit different instance of MockBuilderType after calling disallowMockingUnknownTypes that would still complain about unknown class.

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.

2 participants