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

luisvdbl's avatar

Test similar web and api controllers

Suppose that we have a Post model and we have two separate web and api routes/controllers to create a new post

  • /posts -> PostsController@store
  • /api/posts -> Api/PostsController@store

The web controller would be something like these

<?php

use App\Http\Controllers\Controller;
use use App\Http\Requests\StorePost;
use App\Services\CreatePostService;

namespace App\Http\Controllers;

class ChatMessagesController extends Controller
{
    public function store(StorePost $request, CreatePostService $createPostService)
    {
        // authorization and validations are performed by form request
        
        // any logic for storing the post is perfomerd by the service class
        $post = $createPostService->execute($request->validated());
        
        return redirect()->route('posts.index')->flash('success message');
    }
}

And the api controller will be very similar, the only difference would be that in the response we would return a JsonResource or just the model to be serialized depending on our needs...

Now, usually to test this functionality in the web or api controller, I would do something like these on my tests

<?php

namespace Tests\Feature;

class CreatePostsTest
{
    /* @test */
  public function authorized_users_can_create_new_posts()
  {
      //...
  }

  /* @test */
  public function post_name_is_required()
  {
      //...
  }

  // ... and so on
}

The problem now is, being both controllers so similar (only difference so far is the response), If I want to test the functionality for the other controller, I would have to make tests that are almost the same that the ones in the previous test class.

So my question is ... what would be the ideal way to test both controllers functionality while repeating tests code as little as possible. I have thought about testing the FormRequest and the service class separately and then maybe mock those on my controller tests, but I am not really sure how to do so.

Would really appreciate some help on these!

0 likes
1 reply
bugsysha's avatar

Just do the database assertions in your tests, and then create some post HTTP tests where you differentiate between routes to verify that the correct response has been returned.

How ever you do it, it will have duplication. You can avoid duplication only by extracting common logic or if statements but that is ugly in my opinion.

Please or to participate in this conversation.