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

Mocking new does not work properly in a few cases #42

Closed
wladekb opened this issue May 30, 2016 · 7 comments
Closed

Mocking new does not work properly in a few cases #42

wladekb opened this issue May 30, 2016 · 7 comments

Comments

@wladekb
Copy link

wladekb commented May 30, 2016

The cases which appear not to be handled by uopz (php7):

  • new $variable
  • use Ns\X as Y; new Y;
  • uopz_set_mock('\\Ns\\X',....);

The issues are showcased in the code below:

a.php

<?php

class Foo {}
class Bar {}

$foo = 'Foo';
uopz_set_mock('Foo', 'Bar');

echo get_class(new Foo) . PHP_EOL;  // prints: Bar
echo get_class(new Bar) . PHP_EOL;  // prints: Bar
echo get_class(new $foo) . PHP_EOL; // prints: Foo - incorrect!

ns.php

<?php

namespace SomeNamespace {
    class NsFoo {}
    class NsBar {}
    class NsFoo2 {}
    class NsBar2 {}

    uopz_set_mock('SomeNamespace\\NsFoo', 'SomeNamespace\NsBar');
    uopz_set_mock('\\SomeNamespace\\NsFoo2', '\\SomeNamespace\\NsBar2');

    $nsfoo1 = 'SomeNamespace\\NsFoo';
    $nsfoo2 = '\\SomeNamespace\\NsFoo2';
    echo get_class(new NsFoo) . PHP_EOL;   // prints: SomeNamespace\NsBar
    echo get_class(new NsBar) . PHP_EOL;   // prints: SomeNamespace\NsBar
    echo get_class(new $nsfoo1) . PHP_EOL; // prints: SomeNamespace\NsFoo - incorrect!
    echo get_class(new $nsfoo2) . PHP_EOL; // printf: SomeNamespace\NsFoo2 - incorrect!
}

b.php

<?php

include "ns.php";

use SomeNamespace\NsFoo2 as Foox2;

echo '--- from b.php ---' . PHP_EOL;
echo get_class(new SomeNamespace\NsFoo) . PHP_EOL;  // prints: SomeNamespace\NsBar
echo get_class(new \SomeNamespace\NsFoo) . PHP_EOL; // prints: SomeNamespace\NsBar
echo get_class(new Foox2) . PHP_EOL;                // prints: SomeNamespace\NsFoo2 - incorrect!
echo get_class(new $nsfoo1) . PHP_EOL;              // prints: SomeNamespace\NsFoo - incorrect!
echo get_class(new $nsfoo2) . PHP_EOL;              // prints: SomeNamespace\NsFoo2 - incorrect!

Environment details:

wladek@dev-php7:~/tmp$ php -v
PHP 7.0.2-4+deb.sury.org~trusty+1 (cli) ( NTS )
Copyright (c) 1997-2015 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2015 Zend Technologies
    with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2015, by Zend Technologies
    with Xdebug v2.4.0RC4, Copyright (c) 2002-2016, by Derick Rethans
uopz
uopz support => enabled
Version => 5.0.2-dev

I'd bet all of the constructor calls should return an object of one of the Bar classes but that's not the case as shown in the code even though I actually requested uopz to mock all the Foo classes.

Is it something that could be fixed?

@krakjoe
Copy link
Owner

krakjoe commented May 31, 2016

That last commit fixes most of those bugs, they are mostly caused by the same thing ...

The only outstanding one is the import one ... let me think about that one ...

@maxgoldberg
Copy link

This seems to have broken completely just recently. When I run a.php, I get

Foo
Bar
Foo
PHP 7.0.6 (cli) (built: May  9 2016 13:44:26) ( NTS )
Copyright (c) 1997-2016 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies
    with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies
    with Xdebug v2.4.1-dev, Copyright (c) 2002-2016, by Derick Rethans

$ php -i |grep uopz
uopz
uopz support => enabled

@cmb69
Copy link
Collaborator

cmb69 commented Oct 3, 2017

@maxgoldberg uopz_set_mock() doesn't seem to work at all (anymore) if Xdebug is loaded; see #61.

@JakeQZ
Copy link

JakeQZ commented May 24, 2018

It also does not replace the class where it is extended by another class, e.g.

class A {
  public function __construct() {
    echo "A ctor\n";
  }
  public function who() {
    echo "A\n";
  }
}
class B extends A {
  public function __construct() {
    echo "B ctor\n";
    parent::__construct();
  }
}
class MockA {
  public function __construct() {
    echo "MockA ctor\n";
  }
  public function who() {
    echo "MockA\n";
  }
}
uopz_set_mock(A::class, MockA::class);
$a = new A();
$a->who();
$b = new B();
$b->who();

Expected:

MockA ctor
MockA
B ctor
MockA ctor
MockA

Actual:

MockA ctor
MockA
B ctor
A ctor
A

@krakjoe
Copy link
Owner

krakjoe commented Dec 16, 2018

If there are still outstanding problems here, please open new reports ...

@krakjoe krakjoe closed this as completed Dec 16, 2018
@krakjoe krakjoe mentioned this issue Jan 2, 2019
krakjoe added a commit that referenced this issue Jan 2, 2019
@krakjoe
Copy link
Owner

krakjoe commented Jan 2, 2019

The original code this bug report was opened with works now if you modify the second call to set_mock thus:

    uopz_set_mock('SomeNamespace\\NsFoo2', '\\SomeNamespace\\NsBar2');

It should be documented that class names should be as zend would resolve them, if you wrote that as SomeNamespace\NsFoo2::class you would get the correct class name ...

@cmb69
Copy link
Collaborator

cmb69 commented Jan 2, 2019

It should be documented […]

Done.

salathe pushed a commit to salathe/phpdoc-en that referenced this issue Jan 2, 2019
svn2github pushed a commit to svn2github/phpdoc_en that referenced this issue Jan 4, 2019
heiglandreas pushed a commit to phpdoctest/en that referenced this issue Feb 4, 2020
salathe pushed a commit to salathe/phpdoc-en that referenced this issue Sep 3, 2020
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

5 participants