Imagine I have some controller called PostsController and an Action that creates the post.
class PostsController
{
public function store(CreatePost $createPost)
{
$validated = request()->validate([...]);
$post = $createPost->execute(auth()->user(), $validated);
return $post;
}
}
class CreatePost
{
public function execute(User $user, array $postData)
{
$post = $user->posts()->create($postData);
// ...
return $post;
}
}
If I create a "unit" test of the CreatePost action (where I check that the post is saved in the database with the data passed etc.), would you test the same in the PostsController@store method?
I know in the controller I would test the validation, but not sure if "duplicate" the same asserts (saved correctly in the database etc.)
The responsibility of CreatePost is to persist data; you can test that in isolation of the Controller action. The controller's job is to validate data, and then delegate to the CreatePost class; you can test that by mocking your CreatePost class.
It depends where you draw the boundaries of the feature; it could be argued that the store action and CreatePost class are so closely coupled, everything you need to test could be done in a Feature Test class. Or, if CreatePost is used in other contexts, then separate Unit Test is probably more desirable.
@tykus Thanks for the response.
Actually I have some doubts to implement the validation in the action itself (like Laravel Fortify actions), so I guess the controller test "loses" the validation test...
So in this case, I guess that I should mock the CreatePost class in the controller test, and in the "unit/feature" test of the action, test that data is persisted and validated.