How to fix a chain of methods using the PHPUnit test

I am trying to mock a chain of (nested) methods to return the desired value, this is the code:

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

public function getResults()
{
return $this->db->getFinder()->find($this->DBTable);
}

I tried this layout, but it does not work:

$dbMock = $this->createMock(DB::class);
        $dbMock = $dbMock
            ->expects(self::any())
            ->method('getFinder')
            ->method('find')
            ->with('questions')
            ->will($this->returnValue('7'));

Any solutions how to solve such a problem?

Thank.

+4
source share
2 answers

While @BVengerov his answer will definitely work, I suggest a design change instead. I believe bullying chains are not the way to go, but it hurts the readability and, more importantly, the simplicity of your tests.

I suggest you make the class a Findermember of your class. Thus, now you only need to shout out Finder.

class MyClass {

    private $finder;

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

    public function getResults() {
        return $this->finder->find($this->DBTable);
    }
}

unittesting ( !) .

" $db !" , , , , , . .

, , setFinder(), .

+1

, . . , .

- :

$finderMock = $this->createMock(Finder::class);
$finderMock = $finderMock
    ->expects(self::any)
    ->method('find')
    ->with('questions')
    ->will($this->returnValue('7'));

$dbMock = $this->createMock(DB::class);
$dbMock = $dbMock
    ->expects(self::any())
    ->method('getFinder')
    ->will($this->returnValue($finderMock));

mock chaining .

. 1 () 2 () .

0

Source: https://habr.com/ru/post/1658064/


All Articles