Mocking with using
The using keyword overrides a function or tool implementation inside a test block. This is Cleat's dependency injection mechanism — no framework, no interfaces, just using.
Basic mocking
cleat
test "mock HTTP calls" { using fetch = fn(url: string) -> Result[string, string] { return Ok("{\"status\": \"ok\"}") } let result = fetch("https://api.example.com") assert(result.IsOk()) }
Mocking tools
cleat
tool search(query: string) -> Result[string, string] needs { net } timeout: 10s { return Ok("real results") } test "mock the search tool" { using search = fn(query: string) -> Result[string, string] { return Ok("mock results for: ${query}") } let r = search("test") assert(r.IsOk()) }
The mock signature must match the original tool's parameter and return types.
Why this matters
- Test agents without API keys — mock the tools, verify the agent's behavior
- Test server handlers without network — mock HTTP calls
- Test file operations without disk — mock fs.read/fs.write
- Deterministic, fast, repeatable tests — no external dependencies
Effect bypass in tests
Test blocks can call tools without declaring their effects. This lets you test effectful code without effect boilerplate:
cleat
tool send(text: string) -> Result[string, string] timeout: 5s { return Ok("sent") } test "send works" { let r = send("hello") // no needs { } required in test blocks assert(r.IsOk()) }