Testing
Introduction to Testing
JCC Express MVC includes a full testing layer that mirrors Laravel's approach — you test your app through real HTTP requests, real middleware, and real database queries. There is no HTTP mocking layer; the framework boots a real Express server for each request.
Step 1 — Create your project TestCase
tests/TestCase.ts extends the framework base and tells it how to boot your app:
createApplication() is abstract — you must implement it. It runs once per setUp() call (i.e. before each test).
Step 2 — Write a test
Feature tests use bun:test and live in tests/Feature/:
The new (class extends TestCase {})() pattern creates a one-off anonymous subclass of your TestCase inline. It lets each describe block own its own instance without needing a separate file-level class.
What setUp and tearDown do
setUp() (call in beforeEach):
- Calls
createApplication()— boots Express with all your routes, middleware, providers - Creates an
MakesHttpRequestsinstance wired to that app - Creates an
InteractsWithDatabaseinstance - Connects to the database
tearDown() (call in afterEach):
- Disconnects from the database
How HTTP requests work internally
MakesHttpRequests.call() does the following for every get/post/put/patch/delete call:
- Creates a real
http.createServer(expressApp)instance - Listens on port
0(OS picks a free port) - Makes a
fetch()request tohttp://localhost:<port><uri> - Closes the server after the response is received
- Returns a
TestResponsewrapping the status + body
This means your middleware, route guards, validation, and error handling all run exactly as they do in production.