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.