Undefined function when testing public functions called in the constructor of an abstract class using mockery

StackOverflow https://stackoverflow.com/questions/18771292

  •  28-06-2022
  •  | 
  •  

Question

I have an abstract class which makes calls to public functions in its constructor. To test these calls are executed correctly, I have to mock the abstract class. Whenever I do this, I cannot make public function calls in the constructor. I get the the following error: BadMethodCallException: Method ::setData() does not exist on this mock object. The following code probably explains my issue better.

<?php

namespace Example\Tests;

use Mockery as m;
use PHPUnit_Framework_TestCase;

abstract class Foo
{

    private $data;

    public function __construct(array $defaults)
    {
        foreach ($defaults as $key => $value) {
            $this->setData($key, $value);
        }
    }

    public function getData()
    {
        return $this->data;
    }

    public function setData($key, $value)
    {
        return $this->data[$key] = $value;
    }
}


class ExampleTest extends PHPUnit_Framework_TestCase
{

    public function testDefaultsAreAssignedToData()
    {
        $expected = ['foo' => 'bar'];

        $foo = m::mock('\Example\Tests\Foo', [$expected]);

        $this->assertEquals($expected, $foo->getData());
    }
}
Was it helpful?

Solution

Usually you are using mocks as a replacement for external dependencies for your class under test. In this case you just want to test the real behaviour of the class, and you are not dealing with any dependencies for the class Foo. In this case there is really no need to mock, I would just define a concrete instance of the abstract class for testing purposes. That said, you can refactor to something like this.

class ConcreteFoo extends Foo
{
}

class ExampleTest extends PHPUnit_Framework_TestCase
{
    public function testDefaultsAreAssignedToData()
    {
        $expected = ['foo' => 'bar'];

        $foo = new ConcreteFoo($expected);

        $this->assertEquals($expected, $foo->getData());
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top