Question

I'm writing tests for my current project, made with Zend Framework. Everything's fine, but I have a problem testing the logged users actions/controllers: I need to be logged in to be able to perform the action/controller.

How can I be logged in PHPUnit?

Was it helpful?

Solution

As you are saying you want to test actions/controllers, I suppose you are not writting unit-tests, but functional/integration tests -- ie, working with Zend_Test and testing via the MVC.

Here is a test-function I used in a project, where I'm testing if logging in is OK :

public function testLoggingInShouldBeOk()
{
    $this->dispatch('/login/login');
    $csrf = $this->_getLoginFormCSRF();
    $this->resetResponse();
    $this->request->setPost(array(
        'login' => 'LOGIN',
        'password' => 'PASSWORD',
        'csrfLogin' => $csrf,
        'ok' => 'Login',
    ));
    $this->request->setMethod('POST');
    $this->dispatch('/login/login');
    $this->assertRedirectTo('/');
    $this->assertTrue(Zend_Auth::getInstance()->hasIdentity());
}

Simply : I'm loading the login form, extracting the CSRF token, populating the form, and posting it.

Then, I can test if I'm connected.


With that, you can probably extract the logging-in part, to call it before each one of your tests that require a valid user to be logged-in.

OTHER TIPS

There is another way. On my User entity I have a login() method that puts the user's id into the session and a static variable. What I just do in the test setUp() is call $user->login() and it works. In testing environment sessions are not used (setting Zend_Session::$isUnitTested = true has this effect) and tests rely on the static variable. Just remember to clear the static variable (logout() the user) on tearDown().

I think this article could help you: http://perevodik.net/en/posts/7/ It describes how to create a fake identity you can use to set the environment to a state equivalent to a user being logged in.

In much the same way Pascal is using this function:

$this->_getLoginFormCSRF();

I have created a generic function that returns the value by loading the form using the form element manager:

public function _getCSRFHashValueFromForm($formAlias, $csrfName) { $form = $this->servicemanager->get('FormElementManager')->get($formAlias); return $form->get($csrfName)->getValue(); }

This of course assumes that the CSRF is bound to the form and not within any fieldset etc.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top