Tom B
Tom B

Reputation: 2923

PHPUnit mock interface and class at the same time

I have some code that looks like this:

public function foo(Bar $bar) {
    if ($bar instanceof Iterator) {
        //...
    }
}

To test this I'm using:

$this->getMock('Bar');

However, because my code is looking for an instance of Bar that implements Iterator it essentially has two types. By calling getMock('Bar') or getMock('Iterator') the code is untestable.

How can I make a mock implement an interface? This must be possible, surely?

Upvotes: 1

Views: 4029

Answers (2)

Joanteixi
Joanteixi

Reputation: 527

I think that you can mock the class using the Fully Qualified Name of the interface. Then, the mocked class implements the interface that you need.

Upvotes: -1

edorian
edorian

Reputation: 38961

To mock something PHPUnit will create a subclass of the class you tell it to mock.

If Bar implements Iterator your BarMock will also implement Iterator.

Sample.php

<?php

interface myInterface {

    public function myInterfaceMethod();

}

class Bar implements myInterface {

    public function myInterfaceMethod() {
    }

}

class TestMe {

    public function iNeedABar(Bar $bar) {
        if ($bar instanceOf myInterface) {
            echo "Works";
        }
    }
}

class TestMeTest extends PHPUnit_Framework_TestCase {

    public function testBar() {
        $class = new TestMe();
        $bar = $this->getMock('Bar');
        $class->iNeedABar($bar);
    }

}

Outputs:

phpunit Sample.php 
PHPUnit 3.7.8 by Sebastian Bergmann.

.Works

Time: 0 seconds, Memory: 5.25Mb

OK (1 test, 0 assertions)

Upvotes: 3

Related Questions