Prometheus
Prometheus

Reputation: 300

PHPunit mockobject with interface

I have a model called Service that creates an object from a configInterface in the constructor.

public $config;

public function __construct(   \Vendor\Module\Api\Config $config){
    $this->config = $config;
}

And use the following method

public function Foo(){
    $bar = $this->config->Bar();   
    return 'Config bar = '.$bar;
}

In my Unittest setUp() I create a mockobject like this for my service

 $this->serviceMock = $this->getMock(
        'Vendor\Module\Model\Service',
        ['create'],
        [''],
        '',
        true
    );

This will give me the message that __construct() must be an instance of Vendor\Module\Api\Config

Any idea how I can add the config interface in my service mockobject? I tried to create a new object mockobject for my config interface and pass this in my service object but this will return $bar = $this->config->Bar(); null with the my testcase passing.

Upvotes: 0

Views: 703

Answers (2)

Schleis
Schleis

Reputation: 43690

The third argument of the PHPUnit's getMock method are the arguments that should be passed to the constructor. In your case, you are passing an empty string. This definitely does not match the type hint in your constructor. So the mock construction will fail.

To get around this, you could create a mock of the \Vendor\Module\Api\Config object and place that in the array.

The last parameter that you are using in the getMock method is $callOriginalConstructor. Setting this to false will also solve your problem.

$this->serviceMock = $this->getMock(
        'Vendor\Module\Model\Service',
        ['create'],
        [''],
        '',
        false,
    );

FYI

This method of creating mock objects in PHPUnit has been deprecated. In the current version (6.1) The way to do this would be:

$this->serviceMock = $this->createMock('Vendor\Module\Model\Service');

or

$this->serviceMock = $this->getMockBuilder('Vendor\Module\Model\Service')
                     ->setMethods(['create'])
                     ->disableOriginalConstructor()
                     ->getMock();

Both of which will not call the __construct method of the class being mocked.

Upvotes: 1

sensorario
sensorario

Reputation: 21600

For convenience I always use this form of mocks:

$this->getMockBuilder('Foo\Bar')
    ->disableOriginalConstructor()
    ->getMock();

Upvotes: 2

Related Questions