0

I am writing a unit test for an observer invoking sales_order_place_after event.

SampleObserver

class SampleObserver extends \PHPUnit\Framework\TestCase
{
    public function __construct(
        \Sample\Module\Helper\Credit\Config $helperCreditConfig,
        \Sample\Module\Helper\Credit $helperCredit,
        \Magento\Customer\Helper\Session\CurrentCustomer $currentCustomer,
        \Sample\Module\Api\CreditManagementInterface $creditManagement
    ) {
        $this->helperCreditConfig = $helperCreditConfig;
        $this->helperCredit = $helperCredit;
        $this->currentCustomer = $currentCustomer;
        $this->creditManagement = $creditManagement;
    }

    /**
     * @param \Magento\Framework\Event\Observer $observer
     */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $order = $observer->getEvent()->getOrder();
        if ($this->currentCustomer->getCustomerId()) {
            // do some good stuff with order
        }
    }
}

SampleObserverTest

class SampleObserverTest extends \PHPUnit\Framework\TestCase
{
    public function setUp()
    {
        $objectManager = new ObjectManager($this);

        $this->helperCreditConfigMock = $this->createMock('\Sample\Module\Helper\Credit\Config');

        $this->helperCreditMock = $this->createMock('\Sample\Module\Helper\Credit');

        $this->currentCustomerMock = $this->getMockBuilder('\Magento\Customer\Helper\Session\CurrentCustomer')
            ->disableOriginalConstructor()
            ->setMethods(['getCustomerId'])
            ->getMock();

        $this->creditManagementMock = $this->createMock('\Sample\Module\Api\CreditManagementInterface');

        $this->sendOrderToVenuePay = $objectManager->getObject(
            'Sample\Module\Observer\SendOrderToVenuePay',
            [
                'helperCreditConfig' => $this->helperCreditConfigMock,
                'helperCredit' => $this->helperCreditMock,
                'currentCustomer' => $this->currentCustomerMock,
                'creditManagement' => $this->creditManagementMock
            ]
        );
    }

    public function testExecute()
    {
        $this->eventMock = $this->createPartialMock(
            \Magento\Framework\Event::class,
            ['getOrder']
        );
        $this->eventObserverMock = $this->createMock(
            \Magento\Framework\Event\Observer::class
        );
        $this->eventObserverMock
            ->expects($this->any())
            ->method('getEvent')
            ->willReturn($this->eventMock);

        $this->eventMock
            ->expects($this->atLeastOnce())
            ->method('getOrder')
            ->willReturn($this->returnSelf());

        $this->currentCustomerMock
            ->expects($this->atLeastOnce())
            ->method("getCustomerId")
            ->willReturn($this->any());
    }
}

Following block of code

$this->currentCustomerMock
    ->expects($this->atLeastOnce())
    ->method("getCustomerId")
    ->willReturn($this->any());

throws

1) Sample\Module\Test\Observer\SampleObserverTest::testExecute
Expectation failed for method name is equal to "getCustomerId" when invoked at least once.
Expected invocation at least once but it never occurred.

and following block of code

$this->eventMock
    ->expects($this->atLeastOnce())
    ->method('getOrder')
    ->willReturn($this->returnSelf());

throws

1) Sample\Module\Test\Observer\SampleObserverTest::testExecute
Expectation failed for method name is equal to "getOrder" when invoked at least once.
Expected invocation at least once but it never occurred.

Please help what I am doing wrong? Since I am new to PHPUnit I am unable to figure it out.

0

You never execute your object i.e. $this->sendOrderToVenuePay, to execute this you have to initiated the observer object so right after $this->sendOrderToVenuePay declaretion under setUp() initiate observer object like below

$this->event = new \Magento\Framework\DataObject();
$this->observer = new \Magento\Framework\Event\Observer(['event' => $this->event]);

2nd, replace everything in testExecute with the following code

$this->currentCustomerMock->expects($this->atLeastOnce())
    ->method("getCustomerId")
    ->willReturn(1);

$this->assertEquals($this->sendOrderToVenuePay, $this->sendOrderToVenuePay->execute($this->observer));

The test will be passed successfully but remember if you want to do some good stuff with the order then you must assign an order to event observer to perform further tests, add following lines just before the $this->assertEquals

/** @var \Magento\Sales\Model\Order | \PHPUnit\Framework\MockObject\MockObject $orderMock */
$orderMock = $this->getMockBuilder(\Magento\Sales\Model\Order::class)
    ->disableOriginalConstructor()
    ->getMock();
$this->event->setOrder($orderMock);

Since we are using \Magento\Framework\DataObject so setOrder will act as a magic setter.

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.