.NET SDK reference
TinyConductor.Testing runs a TinyConductor engine in Embedded mode inside your
xUnit test process. It needs no server, database or container, and it keeps
nothing on disk. It behaves exactly like the Embedded mode server, because it
is the Embedded server, running in your process: the same engine and the same
API production runs. Its virtual clock stands still until your test moves
it.
Quickstart
Section titled “Quickstart”The SDK is not on NuGet yet. The release carries it as a package file,
TinyConductor.Testing.0.1.0.nupkg: add the folder that holds it as a local
package source, then dotnet add package TinyConductor.Testing. The SDK also
needs the engine’s native library next to your test assembly. It is in the
lib folder of the TinyConductor release archive for your platform. The
planned NuGet package will carry the library for every platform (the
.NET testing guide shows both steps).
Then deploy the BPMN and form resources, register worker behavior, and make record-backed assertions:
using TinyConductor.Testing;using Xunit;
public sealed class OrderProcessTests : IDisposable{ private readonly EmbeddedEngine _engine = new();
[Fact] public void Order_completes_after_payment_review_period_and_confirmation() { _engine.DeployResource("processes/order.form"); _engine.DeployResource("processes/order-decisions.dmn"); _engine.DeployResource("processes/order.bpmn"); _engine.MockJobWorker("send-invoice").ThenComplete();
var order = _engine.CreateInstance( "order-process", new { orderId = 4711, amount = 99.90 });
_engine.CompleteJob("charge-card", new { charged = true }); _engine.Clock.AdvanceBy(TimeSpan.FromDays(1)); Assert.Single(_engine.UserTasks) .Complete(new { shipped = true, carrier = "dhl" });
TinyConductorAssert.That(order) .IsCompleted() .HasCompletedElements( "charge-card", "shipping-tier", "review-period", "send-invoice", "confirm-shipment") .HasVariable("charged", true) .HasVariable("shippingTier", "standard") .HasVariable("shipped", true); }
public void Dispose() => _engine.Dispose();}processes/order.bpmn, processes/order-decisions.dmn and
processes/order.form are copies of the shared sample files in the
release’s examples download: the same files the quickstart deploys into a
Bundled container. The shipping-tier business rule task evaluates the deployed
decision table in-process, so it needs no mock worker.
The API is synchronous. The engine runs in your process and processes one
call at a time, so async would add noise to your tests without making
anything run in parallel.
Moving the clock waits for the engine to settle. AdvanceBy and AdvanceTo
return only when everything the move caused is visible in the records: the
timers due at the new instant have fired, the engine work they caused has
run, and your registered job-worker mocks have answered.
Jobs have leases, as on a server. ActivateJobs leases each job for 30
seconds of engine time; if your test moves the clock past that before it
completes or fails the job, the job is offered again, and the old
ActivatedJob can no longer complete it.
You can pass variables as anonymous objects, POCOs or dictionaries. Read the
variables of an activated job with job.GetVariable<T>("name").
Process-test assertion mapping
Section titled “Process-test assertion mapping”The package mirrors the assertions of compatible process-testing libraries (see Compatibility):
| Process-test concept | TinyConductor.Testing |
|---|---|
assertion entry point (assertThat(instance)) | TinyConductorAssert.That(instance) |
isCompleted, isActive, isTerminated | IsCompleted(), IsActive(), IsTerminated() |
hasCompletedElements | HasCompletedElements(params string[]) |
hasActiveElements | HasActiveElements(params string[]) |
hasVariable, hasVariables | HasVariable(name, expected), HasVariableNames(params string[]) |
hasNoIncidents, active incident assertion | HasNoIncidents(), HasActiveIncidents() |
| test clock time increase | engine.Clock.AdvanceBy(TimeSpan) |
| test clock absolute time | engine.Clock.AdvanceTo(DateTimeOffset) |
| mocked job worker | engine.MockJobWorker(type).ThenComplete() / ThenThrowError() / ThenHandle(...) |
| job activation and completion | ActivateJobs(type), CompleteJob(type) |
| user-task query and completion | engine.UserTasks, UserTask.Assign(...), UserTask.Complete(...) |
Raw transport escape hatch
Section titled “Raw transport escape hatch”Some Embedded-mode JSON operations have no typed method yet. Send one of
those with engine.Transport.Send(json), which returns the raw JSON response
as a string. Transport details such as JsonDocument are not part of the
public API. If you need an operation often, prefer adding a typed method to
the package.