Session data in phpunittest

In my test controller, in a test action, I am setting the Auth.User session.

$this->session(['Auth' => ['User' => $user->toArray()]]);

But in my Behavior I am not able to get the session data. When I print $_SESSION['Auth'], I get nothing.

I am on CakePHP 4.4 and PHP Unit 9.6

This is where I resort to dd() so I can see what is going on

In methods in your behavior which will be called when you are making your request try:

  dd($_SESSION);
  dd(Router::getRequest()->getSession()->read('Auth'));

In your test method you can see the output of the response or just dump $_SESSION

// controller test class
public function testTimeStampBehavior()
    {
        $this->session(['Auth' => ['id' => 1]]);
        $this->enableCsrfToken();
        $this->post('/users/add', ['username' => 'james', 'password' => 'abc']);
        // dd($this->_response->getBody()->__toString());
        dd($_SESSION);
        $this->assertResponseCode(302);
        $this->assertSessionHasKey('Auth.id');
    }

Output

########## DEBUG ##########
[
  'Auth' => [
    'id' => (int) 1
  ],
  'csrfToken' => 'naGNd/Oa6I0nxTexK5Jn6jE2ZmJkNjI4M2ZmM2ZmOTJhZjQyNTFkNDExOTRlNWJmYWEwNTEzN2Q=',
  'Flash' => [
    'flash' => [
      (int) 0 => [
        'message' => 'The user has been saved.',
        'key' => 'flash',
        'element' => 'flash/success',
        'params' => []
      ]
    ]
  ]
]
###########################

On another note the documentation says Auth.User.id but I’m not seeing that in practice

In CakePHP 4 and 5 when I look at Session in DebugKit I see Auth.id etc not Auth.User.id

Thank you. When I debug I do not see the session variables. But I can see the Flash.

        $this->session(['Auth.User.user_id' => 5]);
        dd($_SESSION);

debug:

PHPUnit 9.6.19 by Sebastian Bergmann and contributors.

E..S^ array:1 [
  "Flash" => array:1 [
    "flash" => array:1 [
      0 => array:4 [
        "message" => "New course code ABCD saved."
        "key" => "flash"
        "element" => "flash/success"
        "params" => []
      ]
    ]
  ]
]

You misunderstand how $this->session() works.

It sets the HTTP Sessions for the next Integration Test call (like $this->get() or $this->post()) but does NOT directly write to the $_SESSION superglobal.

Thank you.

Even then I don’t see the session I set

$this->session(['Auth.User.user_id' => 5]);
$this->enableRetainFlashMessages();
$this->get(['prefix' => 'XXX', 'controller' => 'ControllerName', 'action' => 'actionName']);
dd($_SESSION);

debug: I get only the flash message from actionName method

PHPUnit 9.6.19 by Sebastian Bergmann and contributors.

...S^ array:1 [
  "Flash" => array:1 [
    "flash" => array:1 [
      0 => array:4 [
        "message" => "Invalid course code"
        "key" => "flash"
        "element" => "flash/error"
        "params" => []
      ]
    ]
  ]
]

Ah, okay. I see what you meant! So I will not be able to see the ‘Auth’ session variable in the $_SESSION superglobal.

what you do inside your integration tests doesn’t “bleed out” to your phpunit test

In my behavior.php file, I use the below to check the session variable I set in test

if (isset($_SESSION['Auth']['User']['user_id'])) {

test method:

 $this->session(['Auth.User.user_id' => 5]);

How can I rewrite this since $this->session will not be writing to $_SESSION

behaviors are part of the model, therefore they don’t have access to either the request nor the logged in user directly.

Usually you add GitHub - UseMuffin/Footprint: CakePHP plugin to allow passing currently logged in user to model layer. to your application and therefore have easy access to the logged in user inside your model via the options array.

Otherwise the only way you can access the logged in user inside your behavios is by passing down the logged in user to the method you are calling (e.g. inside your controller)

1 Like

I think my flash message is overwriting the session i set. But I am not quite sure why.

I have this in my controller action

if (!isset($id)) {
            $this->Flash->error(__('Invalid id'));
            return $this->redirect(['prefix' => 'Admin', 'controller' => 'controllerName', 'action' => 'index']);
        }

my test method:

$this->session(['Auth.User.user_id' => 5]);

$this->enableRetainFlashMessages();

$this->get(['prefix' => 'Admin', 'controller' => 'controllerName', 'action' => 'controllerAction']);
dd($_SESSION);

debug:

PHPUnit 9.6.19 by Sebastian Bergmann and contributors.

...S^ array:1 [
  "Flash" => array:1 [
    "flash" => array:1 [
      0 => array:4 [
        "message" => "Invalid id"
        "key" => "flash"
        "element" => "flash/error"
        "params" => []
      ]
    ]
  ]
]

if I remove $this->Flash->error(__('Invalid id')); from my controllerAction, on my debug, I get:

PHPUnit 9.6.19 by Sebastian Bergmann and contributors.

E..S^ array:2 [
  "Auth" => array:1 [
    "User" => array:57 [
      "user_id" => 5

Okay. not Flash, but the redirection after the flash is causing the problem.