Skip to content

Instantly share code, notes, and snippets.

@adrianb93
Created January 17, 2022 01:04
Show Gist options
  • Save adrianb93/9f0bfb50fd9962bff5f0636c13c7696a to your computer and use it in GitHub Desktop.
Save adrianb93/9f0bfb50fd9962bff5f0636c13c7696a to your computer and use it in GitHub Desktop.
How I add "private functions" to a pest test file.
<?php
#
# 1. Add the Macroable trait to your base test.
#
namespace Tests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
use Illuminate\Support\Traits\Macroable;
...
abstract class TestCase extends BaseTestCase
{
...
use Macroable;
...
}
<?php
#
# 2. Add these global helpers (just for a neat developer experience)
#
use Illuminate\Support\Arr;
use Illuminate\Support\Traits\Macroable;
function private_function(string $name, callable $callback)
{
macro($name, $callback, $frame = 2);
}
function macro(string $name, callable $callback, int $frame = 1)
{
$class = Arr::get(debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, $frame + 1), "{$frame}.class", '');
$macroable = class_exists($class) && collect()
->wrap($class)
->merge(class_parents($class))
->map(fn (string $class) => in_array(Macroable::class, class_uses($class)))
->contains(true);
throw_unless($macroable, new Exception('You must call macro from a macroable class.'));
$class::macro($name, $callback);
}
<?php
#
# 3. I use my `private_function` helper to show that this test file has a function called input.
# You could also do `macro('input', fn)` or `$this->macro('input', fn)`. I just prefer
# `private_function('input', fn)` for clear intent that you can call `$this->input(...)`.
#
namespace Tests\Feature;
beforeEach(function () {
private_function('input', function (array $input = []) {
return array_merge([
'name' => 'Happy Path Inputs',
'email' => 'happy@path.inputs',
], $input);
});
});
test('example', function () {
$response = $this->post('/example', $this->input([
'email' => 'this@works.com',
]));
$response->assertSuccessful();
expect(Example::count())->toBe(1);
$example = Example::first();
expect($example->name)->toBe('Happy Path Inputs');
expect($example->email)->toBe('this@works.com');
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment