Testing HTTP Applications
Table of Contents
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()
ortearDown()
method in your test, make sure to callparent::setUp()
orparent::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:
delete()
get()
head()
options()
patch()
post()
put()
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:
withCookies($cookies)
- Sets the cookies in the request
withEnvironmentVars($env)
- Sets the environment vars in the request
withFiles($files)
- Sets the files in the request
$files
must be a list ofOpulence\Http\Requests\UploadedFile
objects
withHeaders($headers)
- Sets the headers in the request
HTTP_
is automatically prepended to the header names
withJson($json)
- Sets the request body to the input JSON
withParameters($parameters)
- Sets the request query to
$parameters
onGET
requests, and sets the request post to$parameters
onPOST
requests
- Sets the request query to
withRawBody($rawBody)
- Sets the raw body in the request
withServerVars($serverVars)
- Sets the server vars in the 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 callroute()
before any assertions defined inIntegrationTestCase
.
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');
}
cookieValueEquals()
Asserts that a response cookie matches an expected value:
public function testCheckingVisitedCookie()
{
$this->get('/home')
->go()
->assertResponse
->cookieValueEquals('visited', '1');
}
hasCookie()
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
}