savvywombat / laravel-test-utils
Utilities and helpers for testing Laravel based applications
Requires
- php: ^7.2
- fzaninotto/faker: ^1.9
- guzzlehttp/guzzle: ^7.0
README
Utilities and helpers for testing Laravel based applications
composer require --dev savvywombat/laravel-test-utils
Database casting helpers
use SavvyWombat\LaravelTestUtils\DBCast
DBCast::toJson
Use this helper when asserting against the database (such as with assertDatabaseHas or assertDatabaseMissing) to cast an array or json string to a JSON datatype.
$this->assertDatabaseHas('vehicles', [ 'id' => 1, 'manufacturer' => 'Toyford', 'model' => 'Llama', 'attributes' => DBCast::toJson([ 'color' => 'indigo green', 'engine' => '2 litres 4-cylinder', 'gearbox' => '6-speed manual', 'doors' => '5', ]), ]);
DBCast::toTimestamp
User this helper to assert Datetime or Carbon instances against timestamps in the database.
$trip = Trip::factory()->create(); Carbon::setTestNow("2020-10-20 10:15:43"); $response = $this->get('/start-trip'); $response->assertStatus(200) ->assertSee('Trip started'); $this->assertDatabaseHas('trips', [ 'id' => $trip->id, 'trip_started_at' => DBCast::toTimestamp(Carbon::now()), ]); Carbon::setTestNow();
Mock guzzle
This trait assumes that you are using Laravel's IoC to inject the Guzzle client into your code.
Say we're testing a contact form with a Google Recaptcha:
namespace App\Http\Controllers; use GuzzleHttp\Client; use Illuminate\Http\Request; class ContactController extends Controller { public function send(Request $request, Client $client) { // Validate ReCaptcha $response = $this->client->post(config('recaptcha.url'), [ 'query' => [ 'secret' => config('recaptcha.secret'), 'response' => $request->input(['g-recaptcha-token'], ''), ] ]); if (json_decode($response->getBody())->success) { redirect()->route('contact::success'); } else { redirect()->route('contact::form')->withErrors(['g-recaptcha-token' => 'Please confirm you are a human!']); } }
namespace Tests\Feature; use GuzzleHttp\Psr7\Response; use SavvyWombat\LaravelTestUtils\MocksGuzzle; use Tests\TestCase; class MyTest extends TestCase { use MocksGuzzle; /** @test */ public function it_reacts_appropriately_to_recaptcha_success() { $this->guzzle() // this is guzzle's MockHandler class ->append(new Response(200, [], json_encode(['success' => 'true']))); $this->post('/some-url', ['message' => 'some message', 'g-recaptcha-token' => 'blah']) ->assertStatus(302) ->assertSessionHasNoErrors() ->assertRedirect('/success'); } /** @test */ public function it_errors_on_recaptcha_failure() { $this->guzzle() // this is guzzle's MockHandler class ->append(new Response(200, [], json_encode(['success' => 'false']))); $this->post('/some-url', ['message' => 'some message', 'g-recaptcha-token' => 'blah']) ->assertStatus(302) ->assertSessionHasErrors('g-recaptcha-token') ->assertRedirect('/some-url'); } }
If your controller or other code needs to make more than one request to an API, you can chain responses to the guzzle handler:
$this->guzzle() ->append(new Response(200, [], json_encode(['invoices' => ['id' => '1245', 'id' => '1247']]))) ->append(new Response(404));
Caveats
Currently, the guzzle mock doesn't assert or check anything regarding what requests you are making - it's just a simple way to test your code's reaction to a particular response without having to actually transmit a request to the remote API.
Support
If you are having general issues with this repository, please contact us via the SavvyWombat website.
Please report issues using the GitHub issue tracker. You are also welcome to fork the repository and submit a pull request.
If you're using this repository, we'd love to hear your thoughts. Thanks!
Licence
This package is licensed under The MIT License (MIT).