I’m trying to make a pest test file easier to read.
Currently, I’ve got some standard tests:
test('can get subscribers latest subscription', function () {
$this->seed(PlansTestSeeder::class);
$this->seed(SubscriptionsTestSeeder::class);
$this->assertDatabaseCount('plans', 2);
$this->assertDatabaseCount('subscriptions', 0);
Subscription::factory()->create([
"plan_id" => Plan::where("slug", "bronze")->first()->id
]);
Subscription::factory()->create([
"plan_id" => Plan::where("slug", "silver")->first()->id
]);
Subscription::factory()->create([
"plan_id" => Plan::where("slug", "silver")->first()->id,
"status" => "expired"
]);
Subscription::factory()->trashed()->create();
$this->assertDatabaseCount('subscriptions', 4);
});
test('can get subscribers active subscriptions', function () {
$this->seed(PlansTestSeeder::class);
$this->seed(SubscriptionsTestSeeder::class);
$silverPlan = Plan::where("slug", "silver")->first();
$subscription1 = Subscription::factory()->create([
"plan_id" => Plan::where("slug", "silver")->first()->id,
"subscriber_id" => 1,
"subscriber_type" => "ApresourcingFrameworkBillingTestsModelsSubscriber",
"created_at" => now()->subDays(2),
"started_at" => now()->subDays(2)
]);
$subscription2 = Subscription::factory()->create([
"plan_id" => $silverPlan->id,
"subscriber_id" => 1,
"subscriber_type" => "ApresourcingFrameworkBillingTestsModelsSubscriber",
"created_at" => now()->subDays(1),
"started_at" => now()->subDays(1)
]);
$user = Subscriber::find(1);
$subscription = $user->latestSubscription();
expect($subscription->id)->toBe($subscription2->id);
});
But to then remind myself what tests I’ve written, I’ve got to scroll up and down the page over and over again.
What I’d like to do is change to something like the following:
test('can get subscribers latest subscription', getLatestSubscription());
test('can get subscribers active subscriptions', getActiveSubscriptions());
function getLatestSubscription() {
/// function code here
});
function getActiveSubscriptions() {
// function code here
});
However, the test functions include references to $this, which is available within the normal closure, but it’s not available in the standard function as I’ve set it up here.
Edit: I’m using the laravel pest plugin – I’m not sure if that makes a difference to the use of $this
Is there any way to get around this?
3
Answers
Got there thanks to some hints in the repliers. Not as tidy as I would have liked, but at least it means all the test('description of test') calls are in one place at the bottom of the php file.
Method 1: just call your function from inside a closure:
Method2: rewrite your
test
function for it to accept function name instead of closure. E.g.:Practice
Consider this, which modifies your spun-out functions to each return an anonymous function, and satisfies the call site you’d like to see:
If you’re comfortable with having the functions as closure variables at the same scope, you can remove one level of function invocation with the following:
Theory
As the Pest
test
function accepts aClosure
for its second argument, and binds that closure to the test case internally, any of the following would behave the same:For your use case the last is likely overkill, but could be useful in situations where you have test cases that differ in just a few ways.