3

I'm new i phpspec and trying to create dummy converter for learning purposes, but I stuck with Call to a member function on a non-object error

Here is my code:

Conver class

private $supportedFormats = ['xml', 'json'];
private $handler;

public function __construct(ConvertHandler $handler)
{
    $this->handler = $handler;
}

public function convert(array $data, $format)
{
    if (!$this->shlouldBeSupportedFormat($format)) {
        throw new \Exception();
    }
    $converter = $this->handler->getConverter($format);

    return $converter->convert($data);
}

public function shlouldBeSupportedFormat($format)
{
    if (!in_array($format, $this->supportedFormats)) {
        return false;
    }

    return true;
}

ConvertHandler class

public function getConverter($format)
{
    $class = "AppBundle\Service\Converter\\".ucfirst($format).'Converter';
    if (class_exists($class)) {
        return new $class();
    } else {
        throw new \Exception();
    }
}

XmlConverter class

public function convert(array $data)
{
    return str_replace(PHP_EOL, '', TypeConverter::toXml($data));
}

This code is working. It returns string in XML format.

Now tests:

ConvertSpec class

function let(ConvertHandler $handler) {
    $this->beConstructedWith($handler);
}

function its_convert_function_should_be_valid()
{
    $this->shouldThrow('Exception')->during('convert', ['sadsa','xml']);
    $this->shouldThrow('Exception')->during('convert', [[],'bad_format']);
}

function it_should_check_if_support()
{
    $this->shlouldBeSupportedFormat('xml')->shouldReturn(true);
    $this->shlouldBeSupportedFormat('bad_format')->shouldReturn(false);
}

function it_should_covert_to_xml(ConvertHandler $handler)
{
    $this->convert(['test' => 'test'], 'xml')->shouldBeString();
    $handler->getConverter('xml')->shouldBeCalled();
}

ConvertHandlerSpec class

function its_get_converter_shouldBe_valid()
{
    $this->shouldThrow('Exception')->during('getConverter', ['wrong_format']);
}

function it_should_return_converter()
{
    $this->getConverter('xml')->shouldReturnAnInstanceOf('AppBundle\Service\Converter\XmlConverter');
}

XmlConverterSpec class

function it_should_implement()
{
    $this->shouldImplement('AppBundle\Service\Converter\ConverterInterface');
}
function it_should_convert()
{
    $this->convert(['test'=>'test'])->shouldBeString();
    $this->convert(['test'=>'test'])->shouldReturn(
        '<?xml version="1.0" encoding="utf-8"?><root><test>test</test></root>'
        );
}

Error when I run a tests: PHP Fatal error: Call to a member function convert() on a non-object in /var/www/phpSpecTest/src/AppBundle/Service/Convert.php on line 25

I'm already trying to fix it for second day, and looking for solution in the web. But still can't find a solution.Any suggest will be appreciated.

Bogdan Dubyk
  • 4,756
  • 7
  • 30
  • 67

1 Answers1

4

You haven't mocked ConverterHandler->getConverter() method in your let spec method. It should be like:

function let(ConvertHandler $handler) {
    $xmlConverter = new XmlConverter(); // OR mock it :)
    $handler->getConverter(Argument::any())->shouldReturn($xmlConverter);
    $this->beConstructedWith($handler);
}
Ziumin
  • 4,800
  • 1
  • 27
  • 34