views:

831

answers:

4

hi there, I'm writing tests for my current project, made with Zend Framework. Everything 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. So my question is: How can I be logged in in PHPUnit? thans for reading :)

+5  A: 

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.

Pascal MARTIN
wow, thanks a lot for this super fast and really good-looking answer.I go trying this right (and looking in google about CSRF ;-) ) now and keep you posted about my results
david parloir
well, I've read about CSRF in the wikipedia, I understand the general idea, please correct me if i'm wrong: this CSRF token is a hidden input with a string identifying the user.I'm not using this kind of protection (I probably should, though), so I've used your code without the 2 lines about CSRF, and it's working great!Thanks a lot Pascal, see you around
david parloir
+1  A: 

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().

Emil Ivanov
hi Emil,thanks for your answer.It is very similar, right. Would you mind post some code of it? (I mean the part of putting the user's id in ZendFramework/PHPUnit session.Actually I am a bit confused, I thaught that wasn't possible because PHPUnit doesn't work like a browser, so your thinking about this could be very interesting for me.
david parloir
Sorry david, I lied to you. :) I took a look at the code and edited the response.
Emil Ivanov
okay, I'm glad that I wasn't totally wrong about session and unit environment.I'll stay with Pascal's solution for now, but it's good to know there are other options out there.Cheers Emil.
david parloir
A: 

I've had issue retaining session after asserting login. Has anyone been able to use session variables were testing. Kindly post samples codes as I've spent countless hours trying to assert some elements required after successful login but the test keeps failing.

Steve
+1  A: 

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.

lukas