'CakePHP4: Convert or cast Cake\ORM\Entity to actual entity for type hinting

Let's say I have a method that is expecting an Invoice entity as a parameter. So I add the type hint Invoice like so:

public function doThatThing (Invoice $invoiceEntity)
{
    // ... operate on $invoiceEntity
}

Unfortunately, when I pass the results of InvoiceTable->get(123), I get the error "TypeError: Argument 1 passed to doThatThing must be an instance of App\Model\Entity\Invoice, instance of Cake\ORM\Entity given..." in my unit tests.

Is there a good way to cast or convert the generic ORM results of ->get() to the specific Entity type that I know it must be?



Solution 1:[1]

@greg-schmidt got me looking in the right direction. I'm afraid my question only mentioned the key clue in passing when I said "in my unit tests."

As it turns out, my unit test has a fake invoice table that extends InvoiceTable. My fake does call setTable and setAlias so that it looks like the real table.

But when I call get() on the fake, the call chain bypasses InvoiceTable, lands in ORM/Table, and eventually calls into ORM/Query. When ORM/Table calls the constructor on ORM/Query, it passes $this, which is an instance of my fake, and not of the real, underlying InvoiceTable (setTable and setAlias have no effect at this point). And as @greg-schmidt guessed,

InvoiceTable is almost certainly not your invoice table implementation

My solution will be to have my fake invoice implement its own get() method which will return the response from a real InvoiceTable.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 MM.