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

jrdavidson's avatar

Testing How many times and correct params of a mock object

I'm trying to write a test that will pass with verifying the write amount of times the action runs with the correct parameters each time. The test below passes but as written doesn't ensure enough is tested.

<?php

class AddPlayersToTeamAction extends BaseGameAction
{
    use AsAction;

    public function handle(Team $team, Collection $players): void
    {
        $players->each(function (array $sideCompetitors, int $sideNumber) use ($team) {
            if (Arr::exists($sideCompetitors, 'teachers')) {
                AddTeachersToTeamAction::run($team, Arr::get($sideCompetitors, 'teachers'), $sideNumber);
            }

            if (Arr::exists($sideCompetitors, 'students')) {
                AddStudentsToTeamAction::run($team, Arr::get($sideCompetitors, 'students'), $sideNumber);
            }
        });
    }
}
test('it adds players to a game', function () {
    $team = Team::factory()->create();
    [$teacherA, $teacherB] = Teacher::factory()->count(2)->create();
    [$studentA, $studentB] = Student::factory()->count(2)->create();
    $players = collect([
        0 => [
            'teachers' => collect([$teacherA]),
            'students' => collect([$studentA]),
        ],
        1 => [
            'teachers' => collect([$teacherB]),
            'students' => collect([$studentB]),
        ],
    ]);

    AddTeachersToMatchAction::shouldRun()->times(2);
    AddStudentsToMatchAction::shouldRun()->times(2);

    AddPlayersToTeamAction::run($team, $players);
});
0 likes
2 replies
tisuchi's avatar

@jrdavidson

Heads-up, I don't use Pest. But in php unit, this could be one of the approaches that I can think of based on your code.

May be it helps you for getting some idea and then tweak your test.

/** @test */
    public function it_adds_teachers_and_students_to_team()
    {
        $team = factory(Team::class)->create();
        $players = new Collection([
            [
                'teachers' => [1, 2],
                'students' => [3, 4],
            ],
            [
                'teachers' => [5, 6],
                'students' => [7, 8],
            ],
        ]);

        $addTeachersToTeamActionSpy = $this->spy(AddTeachersToTeamAction::class);
        $addStudentsToTeamActionSpy = $this->spy(AddStudentsToTeamAction::class);

        $addPlayersToTeamAction = new AddPlayersToTeamAction();
        $addPlayersToTeamAction->handle($team, $players);

        $addTeachersToTeamActionSpy->shouldHaveBeenCalledTimes(4);
        $addStudentsToTeamActionSpy->shouldHaveBeenCalledTimes(4);
    }
jrdavidson's avatar

@tisuchi Unfortunately I don't believe that asserts the correct parameters each time that it gets called.

Please or to participate in this conversation.