Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

DenMette's avatar

Testing Laravel Nova Actions?

How can I write tests for custom Laravel Nova Actions?

In my case, I am writing a small Point of Sales application that allows users to Top Up their accounts, I want to write some tests to make sure I covered all the requirements, but the docs of Nova aren't handy.

/**
 * Perform the action on the given models.
 *
 * @param  Collection<\App\Nova\Participant>  $models
 * @return mixed
 */
public function handle(ActionFields $fields, Collection $models)
{
    if (count($models) > 1) {
        return Action::danger(__('You can only top-up one participant at a time.'));
    }

    $amount = $fields->get('amount');

    $model = $models[0];
    $model->wallet += $amount;
    $model->save();

    return Action::message(__('You did a top-up of &euro; :amount for :name.', [
        'amount' => $amount,
        'name' => $model->name,
    ]));
}
0 likes
2 replies
LaryAI's avatar
LaryAI
AI
Best Answer
Level 58

To write tests for custom Laravel Nova Actions, you can follow these steps:

  1. Create a new test file for your Nova Action. For example, if your Action is called "TopUpParticipant", you can create a file named "TopUpParticipantTest.php" in the "tests/Feature" directory.

  2. In the test file, you can use the Nova facade to perform the action on the given models. You can use the actingAs method to authenticate a user and the post method to send a POST request to the Nova action endpoint.

  3. Write test methods to cover different scenarios. For example, you can write a test method to check if the action returns the correct message when the top-up is successful, and another test method to check if the action returns the correct error message when trying to top-up multiple participants at once.

Here's an example of how the test file could look like:

<?php

namespace Tests\Feature;

use App\Nova\Participant;
use Laravel\Nova\Actions\Action;
use Laravel\Nova\Fields\ActionFields;
use Tests\TestCase;

class TopUpParticipantTest extends TestCase
{
    public function testTopUpParticipant()
    {
        $user = // create or get a user to authenticate as
        $participant = // create or get a participant to top-up

        $response = $this->actingAs($user)
            ->postJson('/nova-api/participants/top-up', [
                'resources' => [$participant->id],
                'fields' => [
                    'amount' => 100,
                ],
            ]);

        $response->assertStatus(200)
            ->assertJson([
                'message' => 'You did a top-up of € 100 for ' . $participant->name,
            ]);

        // Assert that the participant's wallet has been updated correctly
        $this->assertEquals(100, $participant->fresh()->wallet);
    }

    public function testTopUpMultipleParticipants()
    {
        $user = // create or get a user to authenticate as
        $participants = // create or get multiple participants to top-up

        $response = $this->actingAs($user)
            ->postJson('/nova-api/participants/top-up', [
                'resources' => $participants->pluck('id')->toArray(),
                'fields' => [
                    'amount' => 100,
                ],
            ]);

        $response->assertStatus(200)
            ->assertJson([
                'danger' => 'You can only top-up one participant at a time.',
            ]);

        // Assert that the participants' wallets have not been updated
        $participants->each(function ($participant) {
            $this->assertEquals(0, $participant->fresh()->wallet);
        });
    }
}

Make sure to replace the placeholders ($user, $participant, $participants) with the appropriate code to create or get the required user and participant models.

Note: The example assumes that you have set up Laravel Nova and have the necessary routes and authentication in place.

1 like
DenMette's avatar

Larry already gave a good start that I could continue with! So, AI helps. I used ChatGPT myself without success.

You can use postJson or post; I am more in favor of post because the formData is also used during the effective handling.

The resources is a string value that is comma separated. So an array cannot be used. Other than that, everything went smoothly!

Please or to participate in this conversation.