A
A
andriyan0v2016-08-03 18:47:00
PHP
andriyan0v, 2016-08-03 18:47:00

Is it possible to set an expectation for the execution order of mock methods in phpunit?

Good afternoon,
Is it possible to set an expectation for the execution order of mock methods in phpunit? and should it be done in unit tests?
For example, there is a class under test:

<?php

class XXX
{
    private $db;

    public function __construct($db)
    {
        $this->db = $db;
    }

    public function doSomething(array $list)
    {
        $db->truncate();
        foreach ($list as $item) {
            $db->insert($item);
        }
    }
}

And a test for it:
class XXXTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @test
     */
    public function doSomething()
    {
        $xxx = new XXX($this->createDBMock($this->getList()));

        $xxx->doSomething($this->getList())
    }

    private function createDBMock($list)
    {
        $mock = $this->createMock(DB::class);

        $mock
            ->expects($this->once())
            ->method('truncate');

        $mock
            ->expects($this->exactly(count($list)))
            ->method('save')
            ->with($list[0], $list[1]);

        return $mock;
    }

    private function getList()
    {
        return ['foo', 'bar'];
    }
}

If the sequence of method calls in the doSomething method changes, then the tests will not break, but the class logic will break
public function doSomething(array $list)
{
    foreach ($list as $item) {
        $db->insert($item);
    }
    $db->truncate();
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
S
Sergey, 2016-08-03
@andriyan0v

and should it be done in unit tests?

is not necessary, since you are thus hard-wiring yourself to the current implementation. The less your tests know about the code under test, the better. In general, make it a rule that you need to mock either interfaces (and yours is desirable, dependency inversion and all that), or something that communicates with the outside world. Everything else is desirable not to mock so as not to tie tests for implementation.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question