Skip to main content
PolyBot’s test harness lets you exercise your handler code in complete isolation — no bot token, no Telegram servers, no real HTTP. PolyBotClient.RunTest() builds the service provider, swaps in an in-memory PolyTests client, and returns an UpdateMocker that pushes synthetic updates directly into the generated router.

RunTest

Call RunTest(CancellationToken cancellationToken = default) instead of RunPollingAsync(). The method:
  1. Builds the service provider the same way as polling, but skips the bot-token requirement
  2. Resolves the IUpdateHandler (your generated BotRouter)
  3. Registers PolyTests as ITelegramBotClient — fully offline, no network calls
  4. Returns an UpdateMocker bound to that provider and handler
BotClient becomes accessible on the PolyBotClient after RunTest() is called, just like after RunPollingAsync(). Accessing it before either method is called throws InvalidOperationException.

UpdateMocker

UpdateMocker is the test controller returned by RunTest(). It exposes:

Default IDs

All helper methods default to userId = 42 and chatId = 1 (where applicable), so you only specify them when your test exercises multi-user or multi-chat logic:

Return value

Every method returns the Update that was routed, with its auto-assigned IDs populated. This lets you write deterministic assertions about the update sequence:

Asserting outgoing API calls

mock.BotClient.SentRequests is an IReadOnlyList<object> of every request the handler sent through ITelegramBotClient, in order. Filter by request type to assert specific calls:

Complete test example

This example covers a message handler, a /start command, and a callback query — reading configuration from a JSON file and asserting all three outgoing requests:

Pushing arbitrary updates

For update types that don’t have a dedicated helper method, use mock.Update(new Update { ... }) directly. The Id is auto-assigned when it is zero:

Configuration binding in test mode

PolyBotClient binds Configuration exactly the same way in test mode as it does for polling. You can attach a JSON file, environment variables, or in-memory values:
BotToken is not required in test mode — PolyBotClient detects a missing token and silently swaps in PolyTests. You only need a token when calling RunPollingAsync.