phpunit-testingcakephpphpunitcakephp-2.3

CakePHP 2.3 - Unit testing User Login


I thought I have to ask here some help to my problem. I've spend whole evening with this. I have a login method in UsersController like this:

public function login() {

        if ( $this->request->is( 'post' ) ) {
            if ( $this->Auth->login() ) {
                $this->redirect( array( 'controller' => 'reservations', 'action' => 'index' ) );
            } else {
                $this->Session->setFlash( __( 'Login error.' ), 'flashError' );
            }
        }
    }

I trying to test this with PHPUnit, so I can be sure that only valid users can login → after a successful login they will be redirected to a specific page. Here's my testLogin method in UsersControllerTest class:

function testLogin() {

        $UsersController = $this->generate( 'Users', array(
                'components' => array(
                    'Auth' => array( 'user' )
                ),
            )
        );

        $UsersController->Auth->expects( $this->any() )
        ->method( 'user' )
        ->with( 'id' )
        ->will( $this->returnValue( 2 ) );

        $data = array( 'User' => array(
                'student_number' => 1111111,
                'password' => 'qwerty'
            ) );

        //$UsersController->Auth->login( $data['User'] );

        $this->testAction( '/users/login', array( 'data' => $data, 'method' => 'get' ) );
        $url = parse_url( $this->headers['Location'] );
        $this->assertEquals( $url['path'], '/reservations' );
    }

I am still learning the basics of unit testing with CakePHP. I get this error:

PHPUNIT_FRAMEWORK_ERROR_NOTICE
Undefined index: Location
Test case: UsersControllerTest(testLogin)

I have no idea what causes this... What's wrong with my test method and how it should be written?

Thanks!


Solution

  • I got this working with the following code:

    function testLogin() {
    
            //mock user
            $this->Users = $this->generate( 'Users', array(
                    'components' => array(
                        'Security' => array( '_validatePost' ),
                    )
                ) );
    
            //create user data array with valid info
            $data = array();
            $data['User']['student_number'] = 1234567;
            $data['User']['password'] = '[valid password here]';
    
            //test login action
            $result = $this->testAction( "/users/login", array(
                    "method" => "post",
                    "return" => "contents",
                    "data" => $data
                )
            );
    
            $foo[] = $this->view;
            //debug($foo);
    
            //test successful login
            $this->assertNotNull( $this->headers['Location'] );
            $this->assertContains( 'reservations', $this->headers['Location'] );
            $this->assertNotContains( '"/users/login" id="UserLoginForm"', $foo );
    
            //logout mocked user
            $this->Users->Auth->logout();
        }