Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHPUnit Mock multiple different methods

I'm new to Unit test and I'm experimenting with PHPUnit framework.

I have a function that calls two others function:

class Dummy{
    public function dummyFunction(){
        $this->anotherDummyFunction();
        .....
        $this->yetAnotherDummyFunction();
    }
    public function anotherDummyFunction(){

        .....

    }
    public function yetAnotherDummyFunction(){

        .....

    }
}

I want test that the two functions be called when I invoke dummyFunction().

Here the test class:

class TestDummyClass {
    public function testDummyFunction(){

        $dummyClassMock = $this->getMockBuilder('Dummy')
                     ->setMethods( array( 'anotherDummyFunction','yetAnotherDummyFunction' ) )
                     ->getMock();

        $dummyClassMock->expects($this->once())
             ->method( 'anotherDummyFunction' );

        $dummyClassMock->expects($this->once())
             ->method( 'yetAnotherDummyFunction' );

        $dummyClassMock->dummyFunction();
   }
}

Now I've notice that if I mock the Dummy class in this way, the result is

Expectation failed for method name is equal to anotherDummyFunction when invoked 1 time(s). Method was expected to be called 1 times, actually called 0 times.

But If I set the Mock Object in this way

$dummyClassMock = $this->getMockBuilder('Dummy')
                     ->setMethods( array( 'anotherDummyFunction' ) )
                     ->getMock();

the test pass. Lastly, if I set the mock object with setMethods(null), the test fails again

It seems that I could pass an array with only one element, the method that I want check if is called. But I've seen here: https://jtreminio.com/2013/03/unit-testing-tutorial-part-5-mock-methods-and-overriding-constructors/ that setMethods is used for inject the return value of the method passed, so this wouldn't have an effect on the call itself, unless I put the dummyFunction in setMethods (In this case the function will return null without call the other two methods, and in this way yes, the test have to fail)

I've made something wrong? I've seen pieces of code where are more than one methods in setMethods()... Why the test fails if I put tho methods in setMethods?

Thanks

like image 929
Manu Avatar asked Dec 11 '25 10:12

Manu


1 Answers

You are using $this->once(), which means that the test can only pass if the method is called exactly once – in every test case where the mock is used!

What you probably want is $this->any() which does not require the method to be called every time.

like image 100
lxg Avatar answered Dec 13 '25 00:12

lxg



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!