simple_mock

HTTP Mock Server for Testing

MIT License Eiffel 25.02 Design by Contract

Overview

simple_mock is an HTTP mock server library for Eiffel that enables testing of HTTP client code without making real network requests. Define expectations, record requests, and verify calls.

Expectation-Based

Define expected requests and the responses to return. Supports status codes, headers, JSON bodies, and delays.

Flexible Matching

Match URLs with glob patterns (* and ?), require specific headers, and validate request bodies.

Request Recording

Track all received requests for verification. Check if URLs were called and how many times.

Fluent API

Chainable configuration methods for building expectations in a readable, declarative style.

Quick Start

local
    l_mock: SIMPLE_MOCK
do
    -- Create mock server
    create l_mock.make

    -- Set up expectation
    l_mock.expect_get ("/api/users")
        .then_respond_json (200, "[{\"id\": 1}]")

    -- Start server
    l_mock.start

    -- Make HTTP calls to http://localhost:8080/api/users

    -- Verify
    if l_mock.was_requested ("/api/users") then
        print ("API called%N")
    end

    l_mock.stop
end

API Reference

SIMPLE_MOCK (Facade)

FeatureSignatureDescription
makemakeCreate on default port 8080
make_on_portmake_on_port (a_port: INTEGER)Create on specified port
portport: INTEGERServer port number
urlurl: STRINGFull URL (http://localhost:port)
is_runningis_running: BOOLEANIs server accepting requests?
startstartStart the mock server
stopstopStop the mock server
resetresetClear all expectations and history
expectexpect (a_method, a_url: STRING): MOCK_EXPECTATIONCreate expectation
expect_getexpect_get (a_url: STRING): MOCK_EXPECTATIONShorthand for GET
expect_postexpect_post (a_url: STRING): MOCK_EXPECTATIONShorthand for POST
was_requestedwas_requested (a_url: STRING): BOOLEANWas URL requested?
request_countrequest_count (a_url: STRING): INTEGERNumber of requests to URL
verify_all_matchedverify_all_matched: BOOLEANAll expectations matched?

MOCK_EXPECTATION (Builder Pattern)

FeatureSignatureDescription
with_headerwith_header (a_name, a_value: STRING): MOCK_EXPECTATIONRequire header
with_bodywith_body (a_body: STRING): MOCK_EXPECTATIONRequire exact body
with_body_containingwith_body_containing (a_text: STRING): MOCK_EXPECTATIONRequire body substring
then_respondthen_respond (a_status: INTEGER): MOCK_EXPECTATIONSet response status
then_respond_jsonthen_respond_json (a_status: INTEGER; a_json: STRING): MOCK_EXPECTATIONSet JSON response
with_response_headerwith_response_header (a_name, a_value: STRING): MOCK_EXPECTATIONAdd response header
with_delaywith_delay (a_ms: INTEGER): MOCK_EXPECTATIONAdd response delay

Examples

Testing an API Client

test_fetch_users
    local
        l_mock: SIMPLE_MOCK
        l_client: MY_API_CLIENT
    do
        -- Setup mock
        create l_mock.make_on_port (9999)
        l_mock.expect_get ("/api/users")
            .with_header ("Authorization", "Bearer token123")
            .then_respond_json (200, "[{\"id\": 1}]")
        l_mock.start

        -- Test client
        create l_client.make ("http://localhost:9999")
        l_client.set_token ("token123")
        l_client.fetch_users

        -- Verify
        assert ("users fetched", l_client.user_count = 1)
        assert ("api called", l_mock.was_requested ("/api/users"))

        l_mock.stop
    end

URL Pattern Matching

-- Exact match
l_mock.expect_get ("/api/users")

-- Wildcard: matches /api/users, /api/posts, etc.
l_mock.expect_get ("/api/*")

-- Single char: matches /api/user1, /api/user2, etc.
l_mock.expect_get ("/api/user?")

-- Path segment: matches /api/123/items, /api/abc/items
l_mock.expect_get ("/api/*/items")

Simulating Delays

-- Simulate slow response (for timeout testing)
l_mock.expect_get ("/api/slow")
    .then_respond (200)
    .with_delay (5000)  -- 5 second delay