10up / wp_mock

WordPress API Mocking Framework
https://wp-mock.gitbook.io
Other
678 stars 70 forks source link

Unable to mock function to return an empty array. #173

Open peterwilsoncc opened 2 years ago

peterwilsoncc commented 2 years ago

Describe the bug In Distributor, I am attempting to mock a function to return an empty array:

https://github.com/10up/distributor/blob/74ba9c5110de1dfa3415e76eab7d7ffc87b19e49/tests/php/SubscriptionsTest.php#L321-L325

However, the return value is coming back as NULL.

As an alternative approach, I've tried setting the return attribute as a callable function(){ return []; } but the same issue occurs.

To Reproduce

  1. As a reduced test case, create the test:

    public function test_return_empty_array() {
        $post_id = 1;
        \WP_Mock::userFunction(
            '\Distributor\Utils\peters_test_function', [
                'return' => [],
            ]
        );
    
        $this->assertSame( [], \Distributor\Utils\peters_test_function( $post_id ) );
    }
  2. Run phpunit --filter test_return_empty_array
  3. PHP Unit will throw a failure:

    PHPUnit 8.5.26 #StandWithUkraine
    
    F                                                                   1 / 1 (100%)
    
    Time: 2.11 seconds, Memory: 18.00 MB
    
    There was 1 failure:
    
    1) Distributor\SubscriptionsTest::test_return_empty_array
    Failed asserting that null is identical to Array &0 ().
    
    /vagrant/content/plugins/distributor/tests/php/SubscriptionsTest.php:18
    /vagrant/content/plugins/distributor/vendor/10up/wp_mock/php/WP_Mock/Tools/TestCase.php:307
    phpvfscomposer:///vagrant/content/plugins/distributor/vendor/phpunit/phpunit/phpunit:97

Expected behavior Returned values retain type.

Screenshots If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

Additional context

BrianHenryIE commented 5 months ago

This works for a non-namespaced function:

public function test_return_empty_array() {
  $post_id = 1;
  \WP_Mock::userFunction( 'peters_test_function' )
    ->andReturnValues([[]]);

  $this->assertSame( array(), peters_test_function( $post_id ) );
}

This does not work:

\WP_Mock::userFunction( '\Distributor\Utils\peters_test_function' )
    ->andReturnValues([[]]);

but returns

Failed asserting that null is identical to Array &0 ().

rather then

Error : Call to undefined function Distributor\Utils\peters_test_function()

showing the issue rests in the namespace... somehow!

BrianHenryIE commented 5 months ago

This works:

public function test_return_empty_array() {
    $post_id = 1;

    \WP_Mock::userFunction( '\\Distributor\\Utils\\peters_test_function' );

    \Patchwork\redefine('\\Distributor\\Utils\\peters_test_function', function($post_id) {
        return [];
    });

    $this->assertSame( [], \Distributor\Utils\peters_test_function( $post_id ) );
}

protected function tearDown(): void
{
    parent::tearDown();
    \Patchwork\restoreAll();
}