To make it easier to run your tests in your Sprinkle environment, that is with every routes, middlewares and other class registered in your Recipe, UserFrosting provides a base TestCase you can use. You simply need to tell the TestCase to use your Recipe. It will create a simple UserFrosting app instance, and cleanly destroy it when the test is done. It also provides some additional helper methods.
To begin testing your Sprinkle, your test case simply need to extends UserFrosting\Testing\TestCase
. Then, define your Sprinkle Recipe in the $mainSprinkle
property. For example:
<?php
namespace App\MySite\Tests;
use App\MySite\MySite;
use UserFrosting\Testing\TestCase;
/**
* Test case with MySite as main sprinkle
*/
class MyTest extends TestCase
{
protected string $mainSprinkle = MySite::class;
// Your test goes here...
}
You could also use the code above as a new test case, instead of defining $mainSprinkle
in every tests. Instead of naming the class MyTest
, name it MyTestCase
and make every test class extend MyTestCase
.
The biggest advantage is you don't need to use your Recipe. Alternatively, you can create a recipe stub. Simply create a second recipe in your testing directory. This other recipe can register only the class you want to test.
When extending UserFrosting\Testing\TestCase
, you have access to many helper methods and properties.
Property | Description |
---|---|
$this->ci |
Dependency Injection Container |
$this->app |
The Slim App Instance |
$this->userfrosting |
The UserFrosting App Instance |
$this->mainSprinkle |
The main sprinkle identifier |
setUp
method will create the application, while tearDown
will delete the application. All properties needs to be access after invoking the parent method.This methods can be used to create a basic ServerRequestInterface
.
$this->createRequest(
string $method, // The HTTP method : GET, POST, PUT, DELETE, etc.
string|UriInterface $uri, // The URI
array $serverParams = [] // The POST data
): ServerRequestInterface
Example
$request = $this->createRequest('GET', '/index');
$request = $this->createRequest('POST', '/create/foo', ['name' => 'bar']);
$request = $this->createRequest('DELETE', '/api/foo/12');
Same as createRequest
, but for JSON request.
createJsonRequest(
string $method, // The HTTP method : GET, POST, PUT, DELETE, etc.
string|UriInterface $uri, // The URI
?array $data = null // The POST data
): ServerRequestInterface
Pass the request to the Slim App for handling by the routes and controllers.
handleRequest(ServerRequestInterface $request): ResponseInterface
Example
$response = $this->handleRequest($request);
Verify that the given string is an exact match for the body returned. Use assertSame
under the hood.
assertResponse(string $expected, ResponseInterface $response)
Example
$this->assertResponse('fr_FR', $response);
// Same as
$this->assertSame('fr_FR', (string) $response->getBody());
Verify that the given response has the expected status code.
assertResponseStatus(int $expected, ResponseInterface $response)
Example
$this->assertResponseStatus(400, $response);
// Same as
$this->assertSame(400, $response->getStatusCode());
Verify that the given array is an exact match for the JSON returned. Optionally, the key argument can be used to isolate a key from the json array (Support dot notation).
assertJsonResponse(mixed $expected, ResponseInterface $response, ?string $key = null)
Example
$this->assertJsonResponse(['foo' => 'bar'], $response);
$this->assertJsonResponse('bar', $response), 'foo';
// Same as
$this->assertJsonEquals(['foo' => 'bar'], (string) $response->getBody());
$this->assertJsonEquals('bar', (string) $response->getBody(), 'foo');
Reverse of assertJsonResponse
assertNotJsonResponse(mixed $expected, ResponseInterface $response, ?string $key = null)
Asserts json string is valid json and is equals to an array. Optionally, the key argument can be used to isolate a key from the json array (Support dot notation).
assertJsonEquals(mixed $expected, string|ResponseInterface $json, ?string $key = null)
Example
$array = ['result' => ['foo' => true, 'bar' => false, 'list' => ['foo', 'bar']]];
$json = '{"result": {"foo":true,"bar":false,"list":["foo","bar"]}}';
$this->assertJsonEquals($array, $json); // true
Reverse of assertJsonEquals
.
assertJsonNotEquals(mixed $expected, string|ResponseInterface $json, ?string $key = null)
Asserts Json string or response equals the expected structure. Optionally, the key argument can be used to isolate a key from the json array (Support dot notation).
assertJsonStructure(array $expected, string|ResponseInterface $json, ?string $key = null)
Example
$json = '{"result": {"foo":true,"bar":false,"list":["foo","bar"]}}';
$this->assertJsonStructure(['result'], $json);
$this->assertJsonStructure(['foo', 'bar', 'list'], $json, 'result');
Asserts the json has the expected count of items at the given key.
assertJsonCount(int $expected, string|ResponseInterface $json, ?string $key = null)
Example
$json = '{"result": {"foo":true,"bar":false,"list":["foo","bar"]}}';
$this->assertJsonCount(1, $json);
$this->assertJsonCount(3, $json, 'result');
$this->assertJsonCount(2, $json, 'result.list');
Asserts the number of time the $tag is found in $html.
assertHtmlTagCount(int $expected, string|ResponseInterface $html, string $tag)
Example
$html = '<html><div>One</div><div>Two</div><span>Not You</span><div>Three</div></html>';
$this->assertHtmlTagCount(3, $html, 'div');
$this->assertHtmlTagCount(1, $html, 'html');
$this->assertHtmlTagCount(1, $html, 'span');
$this->assertHtmlTagCount(0, $html, 'p');
To methods above can be used to test routes endpoints. The basic concept is to use createRequest
or createJsonRequest
to create the ServerRequestInterface
. Then pass this request to handleRequest
which will invoked the correct route and return the response from the controller. Finally use custom assertions to make sure the response contains the right content.
For example :
$request = $this->createRequest('GET', '/index');
$response = $this->handleRequest($request);
$this->assertResponseStatus(200, $response);
$body = (string) $response->getBody();
// ... Assert Body content
Get:
$request = $this->createJsonRequest('GET', '/api/foo');
$response = $this->handleRequest($request);
// Assert response status & body
$this->assertResponseStatus(200, $response);
$this->assertJsonCount(1, $response);
$this->assertJsonStructure(['bar'], $response);
$this->assertJsonResponse(['bar' => true], $response);
$this->assertJsonResponse(true, $response, 'bar'); // Equivalent to previous line
$this->assertJsonNotEquals(['bar' => false], $response);
Post:
$request = $this->createJsonRequest('POST', '/foo/create', ['name' => 'bar']);
$response = $this->handleRequest($request);
$this->assertResponseStatus(200, $response);
$this->assertJsonResponse([], $response);
// ... Assert "foo" was created