Skip to content

Testing a flow

Build a flow, drive a request through the http.Handler from bb.Handler, and assert on the reply — or unit-test a handler by constructing an agent with bb.FixedModel(...). For structured output, bb.Extract[T] gives you the typed value to assert against. See the package tests under internal/flow and internal/serve for patterns.

Mocks for every public interface

Every package that exports an interface ships a mock.go alongside it, with a Mock<Name> implementation you can inject in place of the real thing — no need to hand-roll a fake per test file. Notably:

  • model.Mock — a model.Model that streams scripted Chunks/ToolCalls or returns a canned Fail/Reject error, with Got/Seen for asserting what was asked.
  • model.MockSchema — a model.Schema (tool argument schema) that returns itself from JSONSchema.
  • agent.MockSchema — an agent.Schema (structured-reply schema) with a settable Err so both the valid and invalid Validate paths are one field away.
  • flow.MockStore — an in-memory flow.Store for durability tests.
  • flow.MockScheduler / flow.MockWebhooks — record Defer/Register calls (in Calls/Hooks) instead of actually scheduling anything, so a test can fire the captured Run itself.
  • engine.MockStore / engine.RecordTracer — the same idea at the pkg/engine layer.

Reach for these before writing a local stub: a test-only reimplementation of an interface that already has a mock is duplication, not isolation.

A tree of flows and agents, disguised as a model.