4

Is there way to test Magento POST controllers actions? E.g. customer login:

Mage_Customer_AccountController::loginPostAction()

I'm using EcomDev_PHPUnit module for test. It works great with basic actions, but I can't invoke POST actions.

$this->getRequest()->setMethod('POST');
// ivokes loginAction instead loginPostAction
$this->dispatch('customer/account/login');
// fails also
$this->dispatch('customer/account/loginPost');
// but this assert pass
$this->assertEquals('POST', $_SERVER['REQUEST_METHOD']);

I would like to make tests more or less like

// ... some setup
$this->getRequest()->setMethod('POST');
$this->dispatch('customer/account/login');
// since login uses singleton, then...
$session = Mage::getSingleton('customer/session');
$this->assertTrue($session->isLoggedIn());

1 Answer 1

13

In customer account controller login and loginPost is two different actions. As for logging in, you need to do something like this:

// Setting data for request
$this->getRequest()->setMethod('POST')
        ->setPost('login', array(
            'username' => '[email protected]',
            'password' => 'customer_password'
        ));

$this->dispatch('customer/account/loginpost'); // This will login customer via controller

But this kind of test body is only required if you need to test login process, but if just want to simulate that customer is logged in, you can create a stub that particular customer is logged in. I used it in few projects. Just add this method to your test case and then use when you need it. It will login customer within single test run and will tear down all the session changes afterwards.

/**
 * Creates information in the session,
 * that customer is logged in
 *
 * @param string $customerEmail
 * @param string $customerPassword
 * @return Mage_Customer_Model_Session|PHPUnit_Framework_MockObject_MockObject
 */
protected function createCustomerSession($customerId, $storeId = null)
{
    // Create customer session mock, for making our session singleton isolated
    $customerSessionMock = $this->getModelMock('customer/session', array('renewSession'));
    $this->replaceByMock('singleton', 'customer/session', $customerSessionMock);

    if ($storeId === null) {
        $storeId = $this->app()->getAnyStoreView()->getCode();
    }

    $this->setCurrentStore($storeId);
    $customerSessionMock->loginById($customerId);

    return $customerSessionMock;
}

Also renewSession method is mocked in above code, because it is using direct setcookie function, instead of core/cookie model, so in command line it produces an error.

Sincerely, Ivan

Sign up to request clarification or add additional context in comments.

4 Comments

Yes! That is... almost working. I noticed that it has to be passed 'adminpost' instead 'adminPost'. Then action is captured - I checked it on a clean Magento 1.6.2.0. And yes, I would like to test login process, not simulate login customer. Thanks for very quick support and great module! greetz
This is very interesting. I was unaware of the dispatch method. could that be a good solution for file uploads as well ??
Thanks Ivan - the loginById() function fixed my problem (customer/session and customer/customer being different when loading a fixture into customer/customer and setting it to the session). Inadvertent fix, but thanks! (@robbieaverill from Twitter)
Ivan, please, correct your answer to change loginPost to loginpost, wasted some time struggling with 404

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.