Magento – Magento 2 magic methods phpunit tests

magento2phpunitunit tests

I've started learning and at the same time writing tests for my Magento 2 custom development. Not a ride in the park. It feels like digging a pit in the sand sometimes. I got to the point where I need to test something like:

$payment->setPaymentReminderSendStatus(true)->save();

Writing something like below won't work.

$this->orderPaymentMockSend->expects($this->once())
    ->method('setPaymentReminderSendStatus')
    ->with($paymentReminderSentStatus)
    ->willReturnSelf()
;

It will fail with the message: Trying to configure method setPaymentReminderSendStatus which cannot be configured because it does not exist, has not been specified, is final, or is static, which is true because the setters and getters are handled by \Magento\Framework\DataObject::__call magic method.

A colleague suggested mocking the payment object like below, but to me it feels a bit like hardcoding.

$this->orderPaymentMockSend = $this->getMockBuilder(Payment::class)
    ->disableOriginalConstructor()
    ->setMethods(['setPaymentReminderSendStatus'])
    ->getMock()
;

I'm also looking at maybe mocking the \Magento\Framework\DataObject object to be able to use the __call method (I don't if this is even possible or if I'm overthinking it).

What would be the best practice in this case?

Best Answer

Here's how I managed to use magic methods :

    /** Mock Customer */
    //Add a magic method to the list of mocked class methods
    $methods = \array_merge(
        \get_class_methods(Customer::class),
        ['getCustomerType']
    );

    $this->customerModelMock = $this->getMockBuilder(Customer::class)
        ->setMethods($methods)
        ->disableOriginalConstructor()
        ->getMock();

    //Now I can mock my magic method !
    $this->customerModelMock->expects(static::any())
        ->method('getCustomerType')
        ->willReturn('professional');
Related Topic