Skip to content

Unit testing without a router

Daniel Frantík edited this page Aug 29, 2026 · 2 revisions

Unit testing without a router (TikFakeConnection)

TikFakeConnection stands in for a real ITikConnection so your tests run in CI with no hardware. It intercepts at CallCommandSync, which means the whole call stack above it — commands, parameters and the O/R mapper — runs through real library code, and only the wire is replaced. Use it to test the code that uses tik4net; to watch a real exchange instead, see Communication debugging.

⚠️ Alpha — ships in v4.0.0-alpha: tested and functional, but the API may still change before the final 4.0 release. See Connection types & capabilities.

Add the tik4net.testing NuGet package to your test project:

dotnet add package tik4net.testing
var conn = new TikFakeConnection()
    .WithEntities(new IpAddress { Address = "10.0.0.1/24", Interface = "ether1" }.WithId("*1"))
    .WithScalarResponse(rows => rows.First() == "/ip/address/add", "*2")
    .WithNonQuery(rows => rows.First() == "/ip/address/set");

var list = conn.LoadAll<IpAddress>();
Assert.AreEqual(1, list.Count());

One page per API level

The fake works at all three levels, and each has its own page of recipes:

Capabilities and async code

TikFakeConnection declares Crud | Listen | AsyncCommands | SafeMode | Tagging — the third means code that awaits Execute*Async can be unit-tested against it. The fake's commands complete synchronously, so an await returns immediately and the test needs no timing tricks. Safe Mode is recorded via counters rather than performed against a real router (see Safe Mode).

It substitutes for the typed connections too

This page and connection types tell you to prefer a typed connection over a runtime Supports check. That advice needs a fake you can actually pass, so TikFakeConnection implements every facet and every composite interface — assign it to an ITikApiConnection, ITikCliConnection, ITikMacCliConnection, ITikRestConnection, ITikWinboxNativeConnection or ITikWinboxNativeMacConnection and it fits:

// The method under test asks for the capable type, as the wiki recommends.
static void Configure(ITikCliConnection cli) => cli.CancellationMode = TikCancellationMode.AbandonAndClose;

ITikCliConnection fake = new TikFakeConnection();
Configure(fake);

It is not claiming to be an API or a CLI connection — a double stands in for whatever the code under test asked for. Capabilities is still what answers "can it", and it is still yours to set. The option facets (RouterMac, AllowInvalidCertificate, CancellationMode, SendTagWithSyncCommand, UseGuiNames, CatalogHandlerCount) are plain settable properties the fake records and does not act on, so a test can arrange configuration and assert on it. Tab-completion is scripted through the Completions dictionary; anything unscripted completes to nothing, because "the router offered no completion" is a real answer.

Assign Capabilities to test the other branch — what your code does against a transport that lacks something:

var conn = new TikFakeConnection { Capabilities = TikConnectionCapability.Crud };
// cmd.ExecuteListAsync() now throws TikConnectionCapabilityNotSupportedException here,
// exactly as it would over Telnet — so the synchronous fallback gets exercised.

The default set is deliberately not "everything": a fake that claims every capability cannot be used to test the fail-closed paths, and claiming one it does not implement (RawCommand) would only move the failure later — the fake implements ITikRawSentenceConnection so it can stand in for a typed connection, but does not perform raw commands. Note it does not report CancelInFlight either — there is no in-flight request to abort. Clear SafeMode from Capabilities to test the branch where a transport has no safe mode (e.g. REST).

See also

Clone this wiki locally