Testing & mocking

Every client accepts an injected transport, so you can unit-test code that uses the SDK without a live API — using each language's standard mocking tool. No network, fully deterministic.

Python — httpx.MockTransport

import httpx
from boostspace import BoostSpace

def handler(request: httpx.Request) -> httpx.Response:
    return httpx.Response(200, json={"id": 1, "name": "Mock Inc"})

bs = BoostSpace("token", system="acme",
                http_client=httpx.Client(transport=httpx.MockTransport(handler)))
assert bs.spaces.get(1).name == "Mock Inc"

TypeScript — a mock fetch

const bs = new BoostSpace({
  token: "t", system: "acme",
  fetch: async () => new Response(JSON.stringify({ id: 1, name: "Mock Inc" }),
    { status: 200, headers: { "content-type": "application/json" } }),
});

PHP — Guzzle MockHandler

use GuzzleHttp\{Client, HandlerStack};
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\Psr7\Response;

$http = new Client(['handler' => HandlerStack::create(new MockHandler([
    new Response(200, [], json_encode(['id' => 1, 'name' => 'Mock Inc'])),
]))]);
$bs = new BoostSpace('t', system: 'acme', http: $http);

Go — a custom RoundTripper

rt := roundTripFunc(func(r *http.Request) (*http.Response, error) {
    body := `{"id":1,"name":"Mock Inc"}`
    return &http.Response{StatusCode: 200, Body: io.NopCloser(strings.NewReader(body)), Header: http.Header{}}, nil
})
bs := boostspace.NewClient("t", boostspace.WithSystem("acme"),
    boostspace.WithHTTPClient(&http.Client{Transport: rt}))

The injected transport still gets the SDK's base URL + auth applied, so your handler sees exactly the request the SDK would send in production. Each language's test suite includes a mock-transport test as a worked example.

Fixtures — sample model instances

Rather than hand-write a full payload for every mock response, use the generated fixture factory: it returns an instance of a resource model with its required fields pre-filled. One factory per resource model.

from boostspace import fixtures
space = fixtures.space(name="Acme")            # overrides merged in
const space = fixtures.space({ name: "Acme" });   // spread overrides
$space = \BoostSpace\Sdk\Fixtures::space();   // then mutate public props
$space->name = 'Acme';
space := boostspace.FixtureSpace()   // then mutate the struct
space.Name = "Acme"

Combine the two: return fixtures.space(...) (serialised) from your mock handler to get a valid response body with almost no boilerplate. Fixtures fill only required fields (deterministic sample values); set anything else the test cares about via overrides / mutation.