This is already tested by Laravel as far as I know, so no need to test it twice. The test you perform right now are the only once that are necessary here!
Testing Controller - Unit Test
in my user controller i have
/**
* Update the specified resource in storage.
*
* @param ProfileEdition $request
* @return \Illuminate\Http\RedirectResponse
*/
public function update(ProfileEdition $request)
{
$command = new UpdateUserProfileCommand($request->user(), $request->only('name', 'email'));
$this->dispatch($command);
return redirect()->route('user.profile');
}
i want to Unit Test it... i have my unit test which test against... if the profile was indeed updated.. and if it was redirected back to the profile page.. but.. how could i test against if the command fired/dispatched?
we have there expectsJobs, expectsEvents but no expectsCommands...
@milewski maybe i am guessing that at the point i fire the expectsJobs.. it will mock it and replace on the Ioc Container then it will never get really executed for real which wouldn't insert the data into the db... now how to do... >.<
That is correct and is how a unit test should be, you just need to write another unit test for your job. Also if you are truly doing unit tests you shouldn't be talking to your database either. You seem to be doing some hybrid of unit tests and functional tests.
Unit tests should be something like this:
/** @test */
function controller_should_update_user()
{
$this->withoutMiddleware();
$this->be(User::first());
$data = [
'name' => 'Updated Name',
'email' => 'updated@email.com'
];
$this->expectsJobs(UpdateUserProfileCommand::class);
$this->route('POST', 'user.profile', $data);
$this->assertRedirectedToRoute('user.profile');
}
/** @test */
function update_user_profile_command_should_save_user()
{
$data = [
'name' => 'Updated Name',
'email' => 'updated@email.com'
];
$user = \Mockery::mock(User::class);
$user->shouldReceive('update')->with($data);
(new UpdateUserProfileCommand($user, $data))->handle();
}
Functional tests should look something like this:
/** @test */
public function it_updates_user_profile()
{
$this->withoutMiddleware();
$this->be(User::first());
$data = [
'name' => 'Updated Name',
'email' => 'updated@email.com'
];
$this->route('POST', 'user.profile', $data);
$this->assertRedirectedToRoute('user.profile');
$this->seeInDatabase('users', ['name' => 'Updated Name']);
}
The idea is that unit tests can run really quick so you run them often/all the time and functional tests take long so you run them less often but regularly.
I tend not to write unit tests for my controllers as I rarely have any logic in them worth testing as it normally gets passed of to jobs or something similar. Functional tests on the other hand do test my controllers and they just ensure that they, and everything they talk to work correctly.
Please or to participate in this conversation.