Rohan
Rohan

Reputation: 13781

How to send headers with phpunit api request?

I am trying to test my web service which is written in laravel 5 using phpunit. I am new to this testing framework. The application uses JWT for authentication which is passed in headers in the requests.

My test look likes so:

$response = $this->call('POST', 'authenticate', [
    'username' => 'carparts',
    'email' => '[email protected]',
    'password' => 'password'
]);

$token = 'Bearer ' . json_decode($response->getContent())->token;

$response = $this->call('POST', 'users', [
    "first_name"    => "Test",
    "last_name"     => "Test",
    "email"         => '[email protected]',
    "password"      => "testing",
    "role"          => "1"
], [], [], [
    'Authorization' => $token
]);

dd($response->getContent());

The token is returned fine but when I try to use in the next request to create a new user, it fails saying the token could not parsed from the request. When I do request()->headers in a middleware to check, even that does not show the header. What am I doing wrong? How to pass headers in a request using PHPUnit?

Upvotes: 6

Views: 8656

Answers (5)

za-ek
za-ek

Reputation: 475

I spent a day digging this problem.

What really happens when you run tests: you run phpunit command and then every request doesn't really sends, it's just run in current instance. It means that calling $this->call() doesn't invoke http request.

Every test case (i.e. test method) calls setUp method which runs createApplication method. All methods required by the kernel for booting up an application run in method setUp() which calls exactly before your test case:

// Middleware
...
// There is nothing related to testCase 

function testCase() {
   // set header
}
// Action
...
// You can use header here

To solve this problem I add method exact before my test case. I still can't change headers but I don't really care. To get custom information I do the following:

// in tests:
function _setHeader() {
  global $_TESTING_X_HEADER;
  $_TESTING_X_HEADER = "some-value";
}
function testCase() {
  // setUp will run with $_TESTING_X_HEADER == "some-value"
  // test goes here
}

// in middleware:
if(App::environment('testing')) {
  $h = global $_TESTING_X_HEADER;
} else {
  $h = request()->header('x-header');
}

Upvotes: 0

Fr4NgUs
Fr4NgUs

Reputation: 476

I'm using PHP unit to do some functional tests.

$client->request('GET','url', [], [], ['HTTP_Authorization' => $token]);

It works for me !

Upvotes: -3

c00p3r.web
c00p3r.web

Reputation: 848

just a wild guess...

check your .htaccess, it must contain

RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

Upvotes: 0

David
David

Reputation: 718

There's a function to translate headers to server vars. Try passing this instead:

$this->transformHeadersToServerVars([ 'Authorization' => $token ])

Upvotes: 4

Alex Blex
Alex Blex

Reputation: 37038

$server argument is an array of server variables, not http headers.
Pass your token as HTTP_AUTHORIZATION:

$response = $this->call('POST', 'users', [
    "first_name"    => "Test",
    "last_name"     => "Test",
    "email"         => '[email protected]',
    "password"      => "testing",
    "role"          => "1"
], [], [], [
    'HTTP_AUTHORIZATION' => $token
]);

Upvotes: 0

Related Questions