0

I wants to create the unit test for this observer class. I tried diff-2 ways but didn't get any help. Can anyone create the unit test for this it would be helpful

<?php
    
    declare(strict_types=1);
    
    namespace VendorName\ModuleName\Observer;
    
    use VendorName\ModuleName\Helper\Connection as SFMCHelper;
    use VendorName\ModuleName\Helper\Queue as QueueHelper;
    use Magento\Framework\Event\Manager;
    use Magento\Framework\Event\ObserverInterface;
    
    class CustomerSaveAfterObserver implements ObserverInterface
    {
        /**
         * @var QueueHelper
         */
        protected QueueHelper $queueHelper;
    
        /**
         * @var SFMCHelper
         */
        protected SFMCHelper $sfmcHelper;
    
        /**
         * @param SFMCHelper  $sfmcHelper
         * @param QueueHelper $queueHelper
         */
        public function __construct(
            SFMCHelper  $sfmcHelper,
            QueueHelper $queueHelper
        ) {
            $this->sfmcHelper = $sfmcHelper;
            $this->queueHelper = $queueHelper;
        }
    
        /**
         * Customer save after event handler
         *
         * @param \Magento\Framework\Event\Observer $observer
         * @return void
         */
        public function execute(\Magento\Framework\Event\Observer $observer)
        {
            $customerId = $observer->getCustomerDataObject()->getId();
            if ($customerId && $this->sfmcHelper->isAutoSyncEnabled()) {
                $this->queueHelper->publishSFMCMessage($customerId, QueueHelper::SFMC_EVENT_CUSTOMER_UPDATE);
            }
        }
    }

Thanks in Advance

1 Answer 1

1
<?php

declare(strict_types=1);

namespace VendorName\ModuleName\Test\Unit\Observer;

use Magento\Framework\Event\Observer;
use VendorName\ModuleName\Observer\CustomerSaveAfterObserver;
use VendorName\ModuleName\Helper\Connection as SFMCHelper;
use VendorName\ModuleName\Helper\Queue as QueueHelper;
/* Change this to your class, don't forget to change the property class */
use Magento\Customer\Api\Data\CustomerInterface as CustomerDataObject;

class CustomerSaveAfterObserverTest extends \PHPUnit\Framework\TestCase
{
    /**
     * @var CustomerSaveAfterObserver
     */
    protected $customerSaveAfterObserver;

    /**
     * @var SFMCHelper
     */
    protected $sfmcHelper;

    /**
     * @var QueueHelper
     */
    protected $queueHelper;

    /**
     * Change this to your class, don't forget to change the import
     * @var CustomerDataObject
     */
    protected $customertDataObject;

    /**
     * @var Observer
     */
    protected $observer;

    /**
     * @return void
     */
    public function setUp(): void
    {
        $this->sfmcHelper = $this->createMock(SFMCHelper::class);
        $this->queueHelper = $this->createMock(QueueHelper::class);

        $this->observer = $this->getMockBuilder(Observer::class)
            ->disableOriginalConstructor()
            ->addMethods(['getCustomerDataObject'])
            ->getMock();

        // Maybe useless depend on your class
        $this->customertDataObject = $this->getMockBuilder(CustomerDataObject::class)
            ->disableOriginalConstructor()
            ->getMockForAbstractClass();

        $this->customerSaveAfterObserver = new CustomerSaveAfterObserver(
            $this->sfmcHelper,
            $this->queueHelper
        );
    }

    /**
     * @return void
     */
    public function testExecute()
    {
        $customerId = '1';
        $this->observer->expects(self::once())
            ->method('getCustomerDataObject')
            ->willReturn($this->customertDataObject);

        $this->customertDataObject->expects(self::once())
            ->method('getId')
            ->willReturn($customerId);

        // I assume this value should be true
        // Implement to fit you method return value
        $this->sfmcHelper->expects(self::once())
            ->method('isAutoSyncEnabled')
            ->willReturn(true);

        // Can be useless depend on your method utility
        $this->queueHelper->expects(self::once())
            ->method('publishSFMCMessage')
            ->with($customerId, QueueHelper::SFMC_EVENT_CUSTOMER_UPDATE);
            //->willReturn(true);

        $this->customerSaveAfterObserver->execute($this->observer);
    }
}
5
  • Hi @DJX Thanks for reply I just use the class use Magento\Customer\Api\Data\CustomerInterface as CustomerDataObject; for customer data object. After run the unit test I got below error Test\Unit\Observer\CustomerSaveAfterObserverTest::testExecute PHPUnit\Framework\MockObject\CannotUseAddMethodsException: Trying to configure method "getId" with addMethods(), but it exists in class "Magento\Customer\Api\Data\CustomerInterface". Use onlyMethods() for methods that exist in the class vendor/vendor/magento-module-modulename/src/Test/Unit/Observer/CustomerSaveAfterObserverTest.php:64
    – Jack
    Commented Aug 9, 2023 at 9:38
  • What's happening when you remove line 59 to 65 ? ($this->customerDataObject = $this->getMockBuilder(...)...->getMock(); )
    – DJX
    Commented Aug 9, 2023 at 9:49
  • Error: Call to a member function expects() on null magento-module-sfmcmagentoconnector/src/Test/Unit/Observer/CustomerSaveAfterObserverTest.php:78 ERRORS! Tests: 1, Assertions: 0, Errors: 1.
    – Jack
    Commented Aug 9, 2023 at 10:06
  • Thanks @DJX After made some changes in code it is working perfectly.
    – Jack
    Commented Aug 9, 2023 at 10:29
  • Ho yeah, you change the getMockbuider() of customertDataObject for a createMock() ? If you have time edit my answer to fit your question.
    – DJX
    Commented Aug 9, 2023 at 13:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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