3
votes

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

1
Well, it's strange, but it worked for me. By the way, are you sure that TestDummyClass is inherited from PHPUnit_Framework_TestCase? And what version of phpunit are you using? Mine is 4.6.9. - Alexander Guz
Thank you Alexander, yes, it inherits from PHPUnit_Framework_TestCase, infact other test pass. I'm working with text sublime and the PHPUnit plugin for text sublime. The version of the phpUnit is 4.6.6 but I don't think I can use a new version because of the plugin. Later I will try with another editor with a new version of phpUnit - Manu

1 Answers

3
votes

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.