Test logout() method

I’m trying to add a test for my logout() method and I need to simulate an user is logged in (I want to avoid any dependency with my login() method). I spent an hour trying to figure out how to do it without any success, which is the right way?

Here is what I have so far:

public function testLogout()
    $this->_controller->Auth->setUser([ 'id' => 1 ]); // ERROR: Call to a member function setUser() on null
    $this->assertSession(1, 'Auth.User.id'); // Check right user is logged in
    $this->get('/users/logout'); // Logout user
    $this->assertSession(null, 'Auth.User'); // Check user is logged out

Thanks in advance!

If you are speaking about unit testing than the question is wrong. In unit tests you WILL NOT be logged in any way. You should mock Auth component to mimic the situation as you were logged in.

That is, I want to mimic the situation an user is logged in so I can test if logout works. I would appreciate any further help on how to do it.

Based on your answer you need selenium and not unit tests. But you can try something like this.

 1  public function testViewAuthenticated()
 2  {
 3      $this->session([  //mock user session
 4          'Auth' => [
 5              'User' => [
 6                  'id' => 1,
 7                  'username' => 'rrd'
 9              ]
 10          ]
 11      ]);
 12      $this->get('/users/logout');
 13      $this->assertRedirect(['controller' => 'Users', 'action' => 'login']);
 14  }

This will mock a user session, than call users/logout and check if the user is redirected to login page. Change the last line to the same what you have when the user logouts.

Thanks for your answer!

I tried to mock the user session that way before asking here but I couldn’t assert the user was logged in.
I was getting “There is no stored session data” because the assertSession() is based on the session instance from the last request.

public function testLogout()
        'Auth' => [
            'User' => [
                'id' => 1
    $this->get('/users'); // Added this line
    $this->assertSession(1, 'Auth.User.id'); // Check user is logged in
    $this->get('/users/logout'); // Logout user
    $this->assertSession(null, 'Auth.User'); // Check user is logged out

I prefer to assert based on session and not redirect. I guess the test is fine now but I still don’t get why it should be done with Selenium instead. Anyway, thanks for your help!

In this unit test you mocked the session. It did not really created, and did not destroyed on logout. You are working with a mock. With selenium you can work with actual sessions.

Any way I am happy if the result is satisfactory for you :slight_smile: