Thanks to visit codestin.com
Credit goes to bowphp.com

Skip to main content
Version: 5.x

Test your application

Introduction​

BowPHP's functional testing API lets you test your APIs fluently using HTTP requests. This API is built around PHPUnit, which means you can leverage the full power of that framework to run your tests. The main HTTP operations (GET, POST, PUT, DELETE, PATCH) are covered, and you can add headers or attachments to your requests.

The TestCase class​

The main class for using the testing API is TestCase, which extends PHPUnit's PHPUnitTestCase class. It provides a simple interface for sending HTTP requests and verifying responses.

Methods of the TestCase class​

Configuration

The base URL for HTTP calls is resolved, in this order:

  1. The test's protected ?string $url property (if set).
  2. The APP_URL environment variable.
  3. The http://127.0.0.1:8080 fallback (the default port of php bow run:server).

To customize the resolution, override the protected getBaseUrl(): string method in your test class.

1. attach(array $attach)​

Adds multipart files / fields to the next request. Attachments are consumed after the call and do not leak into subsequent requests within the same test.

$test->attach([
'file' => new \CURLFile('/path/to/file.jpg')
])->post('/upload');

2. withHeaders(array $headers)​

Replaces the headers applied to all subsequent requests in the test.

$test->withHeaders([
'Authorization' => 'Bearer token',
'Content-Type' => 'application/json',
]);

3. withHeader(string $key, string $value)​

Adds (or replaces) a single header.

$test->withHeader('X-Custom-Header', 'custom_value');

4. get(string $url, array $param = [])​

GET request. Parameters are appended to the query string.

$response = $test->get('/api/users', ['page' => 1]);

5. post(string $url, array $param = [])​

POST request. Combine with attach() to send files.

$response = $test->post('/api/users', ['name' => 'John Doe']);

6. put(string $url, array $param = [])​

PUT request.

$response = $test->put('/api/users/1', ['name' => 'John Updated']);

7. delete(string $url, array $param = [])​

A real HTTP DELETE request (no more _method POST hack).

$response = $test->delete('/api/users/1');

8. patch(string $url, array $param = [])​

A real HTTP PATCH request.

$response = $test->patch('/api/users/1', ['name' => 'John Modified']);

9. head(string $url, array $param = [])​

HEAD request: retrieves only the headers, without a body. Useful for checking the existence of a resource or its metadata.

$response = $test->head('/api/users/1');
$response->assertStatus(200);

10. options(string $url)​

OPTIONS request β€” typically used for CORS preflight.

$response = $test->options('/api/users');

11. visit(string $method, string $url, array $params = [])​

A generic dispatcher based on the HTTP verb. Accepts get, post, put, patch, delete, head, options.

$response = $test->visit('patch', '/api/users/1', ['name' => 'X']);

Complete usage example​

Here is a complete example showing how to set up a functional test with the testing API:

use Bow\Testing\TestCase;

class UserApiTest extends TestCase
{
protected ?string $url = 'http://localhost:8080';

public function testCreateUser()
{
// Add an authorization header
$this->withHeader('Authorization', 'Bearer token');

// Add test data to send in the POST request
$data = [
'name' => 'John Doe',
'email' => '[email protected]'
];

// Perform the POST request
$response = $this->post('/api/users', $data);

// Verify that the response has HTTP status 201
$response->assertStatus(201);
$result = $response->toArray();

// Verify that the name of the created user is correct
$this->assertEquals('John Doe', $result['name']);
}

public function testGetUser()
{
// Make a GET request to retrieve a user
$response = $this->get('/api/users/1');

// Verify that the response has HTTP status 200
$response->assertStatus(200);
$result = $response->toArray();

// Verify that the user ID is correct
$this->assertEquals(1, $result['id']);
}
}

The Response class for functional tests​

info

The Response class lets you manipulate HTTP responses in the context of functional tests with BowPHP. It wraps an object of the HttpClientResponse class and exposes several methods for making assertions about the response.

Methods of the Response class​

1. assertJson(string $message = ''): Response​

Verifies that the response content is in JSON format. If it is not, a test failure will be raised.

$response->assertJson("The response should be in JSON format");

2. assertExactJson(array $data, string $message = ''): Response​

Verifies that the JSON content of the response exactly matches the specified data.

$response->assertExactJson([
'name' => 'John Doe',
'email' => '[email protected]'
], "The JSON response does not match the expected data.");

3. assertContainsExactText(string $data, string $message = ''): Response​

Verifies that the response content exactly matches the given text.

$response->assertContainsExactText("Welcome, John Doe", "The response text does not match.");

4. assertHeader(string $header, string $message = ''): Response​

Verifies that a specific header exists in the response.

$response->assertHeader('Content-Type', "The Content-Type header is missing.");

5. assertArray(string $message = ''): Response​

Verifies that the response content is an array.

$response->assertArray("The response should be an array.");

6. assertContentType(string $content_type, string $message = ''): Response​

Verifies that the response content type matches the one specified.

$response->assertContentType('application/json', "The content type is not 'application/json'.");

7. assertContentTypeJson(string $message = ''): Response​

Verifies that the content type is application/json.

$response->assertContentTypeJson("The content type should be JSON.");

8. assertContentTypeText(string $message = ''): Response​

Verifies that the content type is text/plain.

$response->assertContentTypeText("The content type should be text/plain.");

9. assertContentTypeHtml(string $message = ''): Response​

Verifies that the content type is text/html.

$response->assertContentTypeHtml("The content type should be text/html.");

10. assertContentTypeXml(string $message = ''): Response​

Verifies that the content type is text/xml.

$response->assertContentTypeXml("The content type should be text/xml.");

11. assertStatus(int $code, string $message = ''): Response​

Verifies that the HTTP status code of the response matches the one specified.

$response->assertStatus(200, "The HTTP status is not 200.");

12. assertKeyExists(string $key, string $message = ''): Response​

Verifies that a key exists in the JSON content of the response.

$response->assertKeyExists('id', "The 'id' key is missing in the response.");

13. assertKeyMatchValue(string|int $key, mixed $value, string $message = ''): Response​

Verifies that a specific key in the JSON content of the response matches a specified value.

$response->assertKeyMatchValue('name', 'John Doe', "The name in the response does not match.");

14. assertContains(string $text): Response​

Verifies that the response content contains a specific substring.

$response->assertContains("Welcome", "The text 'Welcome' should be present.");

15. getContent(): string​

Retrieves the raw content of the response.

$content = $response->getContent();

16. toArray(): array|object​

Returns the response content as an array or object (if the content is JSON).

$data = $response->toArray();

17. __call(string $method, array $params = [])​

Allows dynamic calls to the methods of the HttpClientResponse object wrapped in the response.

$response->getCode(); // Calls getCode() on HttpClientResponse

Complete usage example​

Here is a complete example showing how to use the Response class to test an API:

use Bow\Testing\TestCase;

class UserApiTest extends TestCase
{
public function testCreateUser()
{
// Perform a POST request
$data = [
'name' => 'John Doe',
'email' => '[email protected]'
];
$response = $this->post('/api/users', $data);

// Verify that the response has status 201
$response->assertStatus(201, "The HTTP status should be 201");

// Verify that the content is JSON
$response->assertJson("The response should be JSON");

// Verify that the name in the response is correct
$response->assertKeyMatchValue('name', 'John Doe', "The user name is incorrect.");
}

public function testGetUser()
{
// Perform a GET request
$response = $this->get('/api/users/1');

// Verify that the response has status 200
$response->assertStatus(200, "The HTTP status should be 200");

// Verify that the user exists
$response->assertKeyExists('id', "The user ID should exist.");
}
}

References​

Additional documentation

See the official PHPUnit documentation for more information about assertions and advanced features.

Is something missing?

If you run into problems with the documentation or have suggestions to improve the documentation or the project in general, please open an issue for us, or send a tweet mentioning the Twitter account @bowframework or directly on github.