Search code examples
phpunit-testingzend-framework2phpunit

PHPUnit: mock all functions except one in ZendFramework2 Controller


I need to mock a zf2 controller and keep one real function: "getStopWords".
I tried this answer adapted below:

public function createMockExecpt()
{
    // create mock to get names of all functions
    $mock = $this->getMockBuilder('Controller\CollectionsController')->disableOriginalConstructor()->getMock();
    $reflection = new MyReflectionClass($mock);
    $functionsToMock = $reflection->getAllfunctionNamesExcept(["getStopWords"]);

    // create mock but don't mock one function
    return $this->getMock('Controller\CollectionsController', $functionsToMock);
}

but got an error about redefining a class.

// Cannot redeclare Mock_CollectionsController_d61a5651::__clone()

I think this happens because I need an instance of the controller to find out all the functions it has. However I can't make an instance of the controller in this context, which is why I need a mock. But I can't make more than one mock of a class within the same test, so I'm stuck.


Solution

  • My problem was that I thought you need an instance of the class to get all the methods.
    Turns out all you need is the class name!

    public function testGetStopWords()
    {
        // get the class methods the controller has, except getStopWords
        $methodsToMock = array_diff(
            get_class_methods("Controller\CollectionsController"), 
            ["getStopWords"]
        );
    
        // use setMethods to determine which methods to mock
        $mockController = $this->getMockBuilder("Controller\CollectionsController")
                ->setMethods($methodsToMock)
                ->disableOriginalConstructor()
                ->getMock();
    }