skip to Main Content

I am working on a package that uses cookies. In my package, I check for the presence of a cookie, and based on its value, I display content. I’m using Orchestra Testbench for my tests (which uses PHPUnit). In my tests, the route I define returns a 200 success and I am able to display my view. However, currently, cookies are not setting or retrieving properly in my test environment. My code works in production, but not in the testing environment.

Here is an example controller method for my route:

public function __invoke(): View|Closure|string
{
    return view('view', ['cookie' => request()->cookie('name')]);
}

Here is my test method:

public function test_content_shows_with_cookie()
{
    $response = $this->withCookie('name', 'value')
        ->get('/route');

    $response->assertSee('success');
}

I have two problems, although I suspect they are related:

  1. request()->cookie('name') returns null no matter what I do, including the method I describe below.
  2. Using the above approach does not actually set a cookie. E.g. dd($response->headers->getCookies()) returns an empty array. However, the following approach will successfully attach my cookie to the request, although my application is not able to retrieve the cookie:
$response = $this->call('GET', '/route')
    ->withCookie('name', 'value');

So, my question is: can I do what I’m trying to do — evaluate the value of a cookie within my testing environment — with Orchestra Testbench? If yes, what am I doing wrong — and if no, what should I try? (Dusk?)

2

Answers


  1. Chosen as BEST ANSWER

    For whatever reason, request()->cookie('name') doesn't work inside my service (it returns null), but it works inside the Controller for the component I'm testing. So, instead of trying to access the cookie directly in my service, for Controllers that need access to this cookie, I've added a Trait and used it to interact with my service (for which I've also set up a Facade). Although calling request() inside the Controller works, I've decided to pass the Request as an argument. Then, I assign the value of the cookie to a parameter in the service, which I can access from anywhere in my application. This solution works. Here is the trait:

    use packagenameFacadesPackageService;
    use IlluminateHttpRequest;
    
    trait MyTrait
    {
        public function bootMyTrait(Request $request): void
        {
            $value = $request->cookie('name');
    
            if (! is_null($value)) {
                PackageService::setCookie($value);
            }
        }
    }
    

    Here is the service:

    class PackageService
    {
        public ?string $cookie = null;
    
        public function setCookie(string $value): void
        {
            $this->cookie = $value;
        }
    }
    

    And here is the component controller:

    use packagenameFacadesPackageService;
    use packagenameTraitsMyTrait;
    use IlluminateViewComponent;
    
    class MyComponent extends Component
    {
        use MyTrait;
    
        // ...
    }
    

  2. Try:

    $cookies = ['name' => 'value'];
    $response = $this->call('GET', '/route', [], $cookies);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search