atoum / atoum

The modern, simple and intuitive PHP unit testing framework.

Home Page:http://atoum.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Calling static method from interface mock

Meroje opened this issue · comments

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.