Calling static method from interface mock
Meroje opened this issue · comments
Jérôme Foray commented
This is going a little further than #233, only adding a call to the static method.
Here is the new snippet:
<?php
namespace jubianchi\InterfaceMock
{
interface A
{
function foo();
}
interface B
{
static function bar();
}
interface C extends A, B
{
function baz();
}
class D
{
public function __construct(C $provider) { }
}
}
namespace tests\unit\jubianchi\InterfaceMock
{
use atoum;
class D extends atoum
{
public function testFoo()
{
$m1 = new \mock\jubianchi\InterfaceMock\C();
\mock\jubianchi\InterfaceMock\C::bar();
}
}
}
Giving the following output:
$ vendor/bin/atoum -f testfile.php
Failure (1 test, 0/1 method, 1 void method, 0 skipped method, 0 uncompleted method, 0 failure, 1 error, 0 exception)!
> There is 1 error:
=> tests\unit\jubianchi\InterfaceMock\D::testFoo():
==> Error E_WARNING in /Users/jforay/Code/atoum-static-interface-method/test.php on line 34, generated by file /Users/jforay/Code/atoum-static-interface-method/vendor/atoum/atoum/classes/mock/generator.php(205) : eval()'d code on line 47:
call_user_func_array() expects parameter 1 to be a valid callback, cannot access parent:: when current class scope has no parent
> There is 1 void method:
=> tests\unit\jubianchi\InterfaceMock\D::testFoo()
Dumping the generated mock does show there is a call to non-existent parent:
<?php
namespace mock\jubianchi\InterfaceMock {
final class C implements \jubianchi\InterfaceMock\C, \mageekguy\atoum\mock\aggregator
{
public function getMockController()
{
$mockController = \mageekguy\atoum\mock\controller::getForMock($this);
if ($mockController === null)
{
$this->setMockController($mockController = new \mageekguy\atoum\mock\controller());
}
return $mockController;
}
public function setMockController(\mageekguy\atoum\mock\controller $controller)
{
return $controller->control($this);
}
public function resetMockController()
{
\mageekguy\atoum\mock\controller::getForMock($this)->reset();
return $this;
}
public function baz()
{
$arguments = array_merge(array(), array_slice(func_get_args(), 0));
if (isset($this->getMockController()->baz) === false)
{
$this->getMockController()->baz = function() {
};
}
$return = $this->getMockController()->invoke('baz', $arguments);
return $return;
}
public function foo()
{
$arguments = array_merge(array(), array_slice(func_get_args(), 0));
if (isset($this->getMockController()->foo) === false)
{
$this->getMockController()->foo = function() {
};
}
$return = $this->getMockController()->invoke('foo', $arguments);
return $return;
}
public static function bar()
{
$arguments = array_merge(array(), array_slice(func_get_args(), 0, -1));
return call_user_func_array(array('parent', 'bar'), $arguments);
}
public function __construct(\mageekguy\atoum\mock\controller $mockController = null)
{
if ($mockController === null)
{
$mockController = \mageekguy\atoum\mock\controller::get();
}
if ($mockController !== null)
{
$this->setMockController($mockController);
}
if (isset($this->getMockController()->__construct) === true)
{
$this->getMockController()->invoke('__construct', func_get_args());
}
}
public function __call($methodName, $arguments)
{
if (isset($this->getMockController()->{$methodName}) === true)
{
$return = $this->getMockController()->invoke($methodName, $arguments);
return $return;
}
else
{
$this->getMockController()->addCall($methodName, $arguments);
}
}
public static function getMockedMethods()
{
return array (
0 => 'baz',
1 => 'foo',
2 => 'bar',
3 => '__construct',
4 => '__call',
);
}
}
}
I have two issues with this generated code
- obviously, any test that ends up calling this static method will fail
- I don't think there is a way to mock the return value of that method ?
I am happy to help working on a fix, please let me know if you know where I should be looking.