2

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?

2 Answers 2

0

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');
1
  • 1
    this looks pretty much the same with what I'm already doing
    – Radu
    May 15, 2019 at 18:46
0

If your magic function does not have any parameters do the following

$map = [
    ['getProductLabel', [], 'Some Label']
];

/**
getProductLabel is function name,
[] is parameter being passed (in this case empty),
'Some Label' is the return
*/

$mock->method('__call')
      ->willReturnMap($map);

If your magic function has parameters do the following

$map = [
    ['setShippingRates', [true], 'some return'],
];
$mock->method('__call')->willReturnMap($map);

/**
setShippingRates is the function name,
[true] is parameter being passed (1 parameter with value true),
'some return' is the return
*/

The following article explains the steps in detail http://www.rosenborgsolutions.com/phpunit-magento-magic-functions.php

I hope that helps

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.