CodeOath
← All posts
Architecture & Patterns55 min total · 13 parts

Middleware Pipelines Compared: ASP.NET Core, Express.js, and Django

Contents — Part 12 of 13: Testing Middleware
Part 12 of 13 · ~1 min

Testing Middleware

Because middleware is just a function (or a class implementing a narrow interface) that wraps a "next" callable, it's straightforward to test in isolation, without spinning up a full route or server:

def test_maintenance_mode_short_circuits():
    def get_response(request):
        return HttpResponse("should not be reached")

    middleware = MaintenanceModeMiddleware(get_response)
    with override_settings(MAINTENANCE_MODE=True):
        response = middleware(fake_request())

    assert response.status_code == 503
test("auth middleware rejects missing token", () => {
  const req = { headers: {} };
  const res = { status: jest.fn().mockReturnThis(), json: jest.fn() };
  const next = jest.fn();

  authenticate(req, res, next);

  expect(res.status).toHaveBeenCalledWith(401);
  expect(next).not.toHaveBeenCalled();  // confirms the chain was actually short-circuited
});

The pattern in both examples is the same: construct a fake "next layer" (a stub get_response, or a mock next function), call the middleware directly, and assert on whether it called through to the next layer or short-circuited — exactly the two behaviors the whole pattern is built around.