jamiemax
jamiemax

Reputation: 189

PHPUnit - Mocking specific methods of the Magento class being tested

I am testing a class using PHPUnit. I want the method that I'm testing to run as normal, but I want to mock another method in this class in order to return a specific string.

My issue is that I can't seem to create a mock object without overriding the logic of the method i actually want to test.

Here is the code of the class being tested:

class Base_Customer_Model_Observer
{
public function addToVip($observer)
{
    if ($this->isRequestFromVipPage() == "true")
    {
        $customer = $observer->getEvent()->getCustomer();
        if ($customer->getGroupId() != 6)
        {
            $customer->setGroupId(6);
            $customer->save();
            Mage::getSingleton('core/session')->addSuccess('You have now been added to our VIP secret sales list');
        }
        else
        {
            Mage::getSingleton('core/session')->addSuccess('You are already on the list!');
        }
    }
}

private function isRequestFromVipPage() {
    return Mage::app()->getRequest()->getPost('vip_list');
}
}

Here is my test class:

class Base_Customer_Test_Model_Observer extends EcomDev_PHPUnit_Test_Case
{

public function testUserIsAddedToVipList()
{

    $mock = $this->getModelMockBuilder('customer/customer')
        ->disableOriginalConstructor()
        ->setMethods(array('save'))
        ->getMock();

    $mock->expects($this->once())
            ->method('setGroupId')
            ->with(6);

    $eventObserver = new Varien_Event_Observer(array('event' => new Varien_Event(array('customer' => $mock))));

    $observer = $this->getModelMockBuilder('base_customer/vip_observer')
        ->setMethods(array('isRequestFromVipPage', 'addToVip'))
        ->getMock();

    $observer->expects($this->once())
        ->method('isRequestFromVipPage')
        ->will($this->returnValue('true'));

    $observer->addToVip($eventObserver);

}

}

Upvotes: 3

Views: 1885

Answers (1)

Cristik
Cristik

Reputation: 32923

You can use a partial mock (https://phpunit.de/manual/current/en/test-doubles.html#test-doubles.mock-objects), and do your asserts on the partial mock instead of creating a new test object. For example:

$eventObserver = $this->getMock('Varien_Event_Observer',array('isRequestFromVipPage'), array('event' => new Varien_Event(array('customer' => $mock))))

will give you an object with only isRequestFromVipPage being replaced by PHPUnit. You can then configure this method to return whatever you need.

Upvotes: 1

Related Questions