Testing HTTP Applications

Table of Contents

  1. Introduction
  2. Testing Routes
    1. Passing Parameters
    2. JSON
    3. with() Methods
    4. Mock Requests
  3. Response Assertions
    1. contentEquals()
    2. cookieValueEquals()
    3. hasCookie()
    4. hasHeader()
    5. headerEquals()
    6. isInternalServerError()
    7. isNotFound()
    8. isOK()
    9. isUnauthorized()
    10. jsonContains()
    11. jsonContainsKey()
    12. jsonEquals()
    13. redirectsTo()
    14. statusCodeEquals()
  4. View Assertions
    1. hasVar()
    2. varEquals()
  5. Middleware
    1. Disabling All Middleware
    2. Disabling Specific Middleware
    3. Enabling Specific Middleware

Introduction

Opulence gives you a powerful integration testing tool to simulate routes and test the responses and views created by controllers. The tool is the Opulence\Framework\Http\Testing\PhpUnit\IntegrationTestCase class, which extends PHPUnit's PHPUnit_Framework_TestCase. By extending IntegrationTestCase, you'll inherit many methods to help test your application.

Note: If you need to define a setUp() or tearDown() method in your test, make sure to call parent::setUp() or parent::tearDown().

Testing Routes

Opulence provides a fluent interface to test your routes. For example, here's how you can make a POST request to /foo with some data:

public function testPostingSomeData()
{
    $this->post('/foo')
        ->withParameters(['bar' => 'baz'])
        ->go()
        ->assertResponse
        ->contentEquals('Nice POST request');
}

The following methods create an Opulence\Framework\Http\Testing\PhpUnit\RequestBuilder, which is useful for creating your requests:

Passing Parameters

If you're testing a GET request and would like to pass some parameters along with it, use withParameters():

public function testWithParameters()
{
    $this->get('/login')
        ->withParameters(['ref' => 'http://google.com'])
        ->go()
        ->assertResponse
        ->redirectsTo('http://google.com');
}

JSON

To simulate passing JSON data to a route, use withJson(). To assert that a JSON response matches an array, use jsonEquals():

public function testJsonRequest()
{
    $this->post('/api/auth')
        ->withJson(['username' => 'foo', 'password' => 'bar'])
        ->go()
        ->assertResponse
        ->jsonEquals(['error' => 'Invalid username/password']);
}

with() Methods

The following methods can be used to pass data to your request:

Mock Requests

If you want fine-grained control over your tests, you can pass in a Request object to IntegrationTestCase::route():

public function testPostingSomeData()
{
    $request = new Request(['name' => 'Dave'], [], [], [], [], []);
    $this->route($request);
    $this->assertResponse
        ->contentEquals('Hello, Dave');
}

Note: If you're not using a RequestBuilder, you must call route() before any assertions defined in IntegrationTestCase.

Response Assertions

You can run various assertions on the response returned by the Kernel. To do so, simply use $this->assertResponse.

contentEquals()

Asserts that the response's content matches an expected value:

public function testContent()
{
    $this->get('/404')
        ->go()
        ->assertResponse
        ->contentEquals('Page not found');
}

Asserts that a response cookie matches an expected value:

public function testCheckingVisitedCookie()
{
    $this->get('/home')
        ->go()
        ->assertResponse
        ->cookieValueEquals('visited', '1');
}

Asserts that a response has a cookie with a particular name:

public function testCheckingVisitedCookie()
{
    $this->get('/home')
        ->go()
        ->assertResponse
        ->hasCookie('visited');
}

hasHeader()

Asserts that a response has a header with a particular name:

public function testCheckingCacheControl()
{
    $this->get('/profile')
        ->go()
        ->assertResponse
        ->hasHeader('cache-control');
}

headerEquals()

Asserts that a response header matches an expected value:

public function testCheckingCacheControl()
{
    $this->get('/profile')
        ->go()
        ->assertResponse
        ->headerEquals('cache-control', 'no-cache, must-revalidate');
}

isInternalServerError()

Asserts that a response is an internal server error:

public function testBadRequest()
{
    $this->get('/500')
        ->go()
        ->assertResponse
        ->isInternalServerError();
}

isNotFound()

Asserts that a response is not found:

public function test404()
{
    $this->get('/404')
        ->go()
        ->assertResponse
        ->isNotFound();
}

isOK()

Asserts that a response is OK:

public function testHomepage()
{
    $this->get('/')
        ->go()
        ->assertResponse
        ->isOK();
}

isUnauthorized()

Asserts that a response is not authorized:

public function testUserListPageWhenNotLoggedIn()
{
    $this->get('/users')
        ->go()
        ->assertResponse
        ->isUnauthorized();
}

jsonContains()

Asserts that a JSON response contains the key/value pairs anywhere in the response. This does not require strict equality like jsonEquals().

public function testJsonResponse()
{
    $this->get('/user/123')
        ->go()
        ->assertResponse
        ->jsonContains(['name' => 'Dave']);
}

jsonContainsKey()

Asserts that a JSON response contains the key anywhere in the response.

public function testJsonResponse()
{
    $this->get('/user/123')
        ->go()
        ->assertResponse
        ->jsonContainsKey('name');
}

jsonEquals()

Asserts that a JSON response matches an input array when decoded:

public function testJsonResponse()
{
    $this->get('/api/auth')
        ->go()
        ->assertResponse
        ->jsonEquals(['foo' => 'bar']);
}

redirectsTo()

Asserts that the response is a redirect to a particular URL:

public function testMyRedirect()
{
    $this->get('/myaccount')
        ->go()
        ->assertResponse
        ->redirectsTo('/login');
}

statusCodeEquals()

Asserts that a response's status code equals a particular value:

public function testPaymentRequiredOnSubscriptionPage()
{
    $this->get('/subscribers/reports')
        ->go()
        ->assertResponse
        ->statusCodeEquals(ResponseHeaders::HTTP_PAYMENT_REQUIRED);
}

View Assertions

If your controller extends Opulence\Routing\Controller, you can test the view set in the response using $this->assertView.

hasVar()

Asserts that the view generated by the controller has a particular variable:

public function testCssVariableIsSet()
{
    $this->get('/home')
        ->go()
        ->assertView
        ->hasVar('css');
}

varEquals()

Asserts that the view generated by the controller has a particular variable with an expected value:

public function testCssVariableIsSet()
{
    $this->get('/home')
        ->go()
        ->assertView
        ->varEquals('css', ['assets/css/style.css']);
}

Middleware

You can customize which middleware are run in your tests.

Disabling All Middleware

You may disable all middleware in your kernel:

public function testWithoutMiddleware()
{
    $this->kernel->disableAllMiddleware();
    // ...Do your tests
}

Disabling Specific Middleware

You may disable only specific middleware in your kernel:

public function testWithoutSpecificMiddleware()
{
    $this->kernel->onlyDisableMiddleware(['MyMiddlewareClass']);
    // ...Do your tests
}

Enabling Specific Middleware

You may enable only specific middleware in your kernel:

public function testWithSpecificMiddleware()
{
    $this->kernel->onlyEnableMiddleware(['MyMiddlewareClass']);
    // ...Do your tests
}