@Talinon Thanks so much for your suggestions!
Annoyingly I can't reduce the request body so much because half of it is required for the form validation rules and isn't part of the user's attributes (of course I didn't expect you to know that or anything).
In any case, it was definitely a move in the right direction as I have swapped out some unnecessary code including the eloquent call by utilising the $user that I created (or make()'d) with the factory.
Right now I've got it looking like this...
public function setUp()
{
parent::setUp();
$this->seedDatabase(); // seeds the database with roles which are assigned on user creation
}
/** @test */
public function a_user_can_register()
{
Mail::fake();
NoCaptcha::shouldReceive('verifyResponse')
->once()
->andReturn(true);
$user = factory(App\Models\User::class)->states('non-verified')->make();
$response = $this->json('POST', '/register',
array_merge($user->toArray(), [
'account_type' => 'personal',
'password' => '123456',
'password_confirmation' => '123456',
'g-recaptcha-response' => '1',
])
);
$response->assertRedirect('/auth/verification/sent');
$this->assertDatabaseHas('users',
array_merge($user->toArray(), [
'verified' => 0,
])
);
Mail::assertSent(VerificationTokenGenerated::class, function ($mail) use ($user) {
return $mail->hasTo($user->email);
});
}
I'm still playing with the idea of abstracting the arrange and act parts into a single method then separating the assertions into their own methods. I'm trying to reach a place where it seems more readable which is why I've kept the act step (the POST request) assigned to the $response variable as I find it easier to read as I've already got the array merge going on inside the request body which honestly I don't like that much but I'll just leave it as it is for now and see if I get any fresh perspective later. Perhaps I'll separate the request body build up into its own variable so it's easier to reason about? Something like ...
$data = array_merge($user->toArray(), [
'account_type' => 'personal',
'password' => '123456',
'password_confirmation' => '123456',
'g-recaptcha-response' => '1',
]);
$response = $this->json('POST', '/register', $data);