Summer Sale! All accounts are 50% off this week.

jrdavidson's avatar

Testing values passed to view

I'm currently trying to update an older feature test where I need to verify which users are being passed to the view for purposes of a dropdown. I'm not sure what the right route is to handle verifying the users passed. I'm providing a couple of ideas below.

A) Go ahead and run the repository query in the test and pass those results to the assertViewHas has assertion. B) Collect the ids of the users that should be passed to the view and add those results to the assertViewHas assertion. C) Some other option that is better.

Any feedback is welcomed. Thank you in advance.

test('the correct users are available to join a  team', function () {
    $user1 = User::factory()->typeA()->create();
    $user2 = User::factory()->typeB()->create();
    $user3 = User::factory()->type3()->create();

    $usersAbleToBeAddedToNewTeam = UserRepository::getAvailableUsersForNewTeam()->pluck('name', 'id');

    $this->actingAs(administrator())
        ->get(action([TeamsController::class, 'create']))
        ->assertStatus(200)
        ->assertViewIs('teams.create')
        ->assertViewHas('users', $usersAbleToBeAddedToNewTeam);
});
public function create()
{
    return view('teams.create', [
        'users' => UserRepository::getAvailableUsersForNewTeam()->pluck('name', 'id'),
    ]);
}
0 likes
2 replies
martinbean's avatar
Level 80

@jrdavidson This is where mocking would come in. You’d mock the repository call to return a set of known users, and test that those users’ details end up in the page using assertSeeText or something. But I don’t really understand how your repository works when it’s just horrible static methods, and not being resolved by the container.

Ideally, your test should look something like this:

$dummyUsers = [
    new User(['name' => 'Available User 1']),
    new User(['name' => 'Available User 2']),
    new User(['name' => 'Available User 3']),
];

$this->mock(UserRepository::class, function (MockInterface $mock) use ($dummyUsers) {
    $mock->shouldReceive('getAvailableUsersForNewTeam')->andReturn($dummyUsers);
});

$this
    ->actingAs($this->admin)
    ->get('/teams/create')
    ->assertOk()
    ->assertViewIs('teams.create')
    ->assertViewHas('users', $dummyUsers)
    ->assertSeeText('Available User 1')
    ->assertSeeText('Available User 2')
    ->assertSeeText('Available User 3');

This assumes the repository method returns an array of User models. If it returns a collection, return a collection instance instead.

This way, you’re testing exactly what you want to test: whether some users end up in the view, and not concerned about other parts (the repository, which should have its own tests).

1 like

Please or to participate in this conversation.