XBullet.EasyTesting.AzureFunctions
1.3.0
dotnet add package XBullet.EasyTesting.AzureFunctions --version 1.3.0
NuGet\Install-Package XBullet.EasyTesting.AzureFunctions -Version 1.3.0
<PackageReference Include="XBullet.EasyTesting.AzureFunctions" Version="1.3.0" />
<PackageVersion Include="XBullet.EasyTesting.AzureFunctions" Version="1.3.0" />
<PackageReference Include="XBullet.EasyTesting.AzureFunctions" />
paket add XBullet.EasyTesting.AzureFunctions --version 1.3.0
#r "nuget: XBullet.EasyTesting.AzureFunctions, 1.3.0"
#:package XBullet.EasyTesting.AzureFunctions@1.3.0
#addin nuget:?package=XBullet.EasyTesting.AzureFunctions&version=1.3.0
#tool nuget:?package=XBullet.EasyTesting.AzureFunctions&version=1.3.0
XBullet.EasyTesting.AzureFunctions
In-memory test infrastructure for .NET isolated Azure Functions, including function contexts, middleware, bindings, retry state, Durable orchestration activity dispatch, and fluent trigger data.
The package targets .NET 8, .NET 9, and .NET 10.
Install
dotnet add package XBullet.EasyTesting.AzureFunctions
Example
await using var host = AzureFunctionTestHost.CreateBuilder()
.AddFunction<ProcessOrderHttpFunction>()
.Build();
var request = host.HttpRequest(nameof(ProcessOrderHttpFunction))
.WithMethod(HttpMethod.Post)
.WithUrl("/api/orders")
.WithJsonBody(new CreateOrderRequest("order-42", 3))
.Build();
var function = host.GetRequiredService<ProcessOrderHttpFunction>();
var response = await function.RunAsync(request, request.FunctionContext);
Builders are available for HTTP, timer, Kafka, Service Bus, Queue Storage, Blob, Event Grid, and Event Hubs triggers.
To reuse a Functions application's Program.cs, derive from
AzureFunctionTestFactory<TEntryPoint>, override ConfigureHost, ConfigureTestHost, or
ConfigureTestServices as needed, and await CreateHostAsync(cancellationToken). The factory
captures the production generic host at construction, retains its configuration and service
registrations, and exposes the existing invocation and scenario APIs without starting hosted
services or worker transport. It owns the returned host and must be asynchronously disposed.
Worker-native middleware requires explicit registration through ConfigureTestHost for in-process
invocation. Startup code before host construction still executes; see the
factory guide
for lifetime, cancellation, and timeout behavior.
Use UseScenarioResource(name, resource) to register borrowed state implementing the shared
ITestScenarioResource contract, then RunInTestScenarioScopeAsync to reset it before and after
setup, multiple invocations, and assertions. Scenarios on one host are serialized, and every
invocation still owns a fresh DI scope. FunctionScenario and FunctionScopedTest provide guarded
domain setup and a test runner without an ASP.NET factory. The package references
XBullet.EasyTesting for shared scenario resource, cleanup, and diagnostic contracts.
Invocation and scenario failures attach TestScenarioDiagnostics before cleanup. Original
exceptions and cancellation tokens are preserved when cleanup fails; aggregated cleanup errors
are attached in exception.Data. Registered resources remain caller-owned. Host singleton services
persist between scenarios unless they participate in the registered reset lifecycle.
HTTP starters accepting [DurableClient] DurableTaskClient can receive a TestDurableTaskClient
through the invocation delegate:
await using var client = new TestDurableTaskClient();
var response = await starter.RunAsync(request, client, cancellationToken);
var start = Assert.Single(client.ScheduledOrchestrations);
Assert.Equal("ProcessOrder", start.OrchestratorName.Name);
Scheduling records input and options and returns an explicit instance ID or a generated
test-instance-N ID. ScheduleHandler can provide custom results or failures and receives the
caller token. The SDK's CreateCheckStatusResponse and CreateCheckStatusResponseAsync helpers
work with the existing test HTTP requests and worker serializer. No orchestration executes
automatically and generated management URLs are not served by the test host. See the
starter guide
for handler configuration and runtime boundaries.
TestOrchestrationMetadataBuilder creates fixtures for status endpoints, including typed input,
output, custom status, tags, failures, and deterministic timestamps. Seed fixtures with
client.WithInstance(metadata). Default lookups honor getInputsAndOutputs; explicit lookup
handlers override fixtures. Management handlers cover termination, purge, restart, rewind, and
history retrieval without changing fixture state automatically.
client.Operations records all validated attempts in invocation order, including handler failures.
Use client.Should().HaveScheduledOrchestration("ProcessOrder"), HaveRaisedEvent, HaveOperation,
and HaveOperationSequence to verify calls. Register the client with UseScenarioResource to
capture a timeline on scenario failure and reset calls, fixtures, and generated IDs around scenarios.
Handlers survive reset. Diagnostics include names, IDs, targets, and statuses while excluding
payloads, options, reasons, and failure details. See the
client guide
for operation arguments, metadata projection, assertions, and cleanup behavior.
TestDurableWorkflow connects the client to named real orchestrator and activity delegates. Attach
an existing host with UseHost, register AddOrchestrator and AddActivity delegates, then pass
workflow.Client to the starter. Execution uses host middleware and a fresh DI scope per function.
Use GetResultAsync<T> to await results, client events to route approvals by instance ID, and
GetContext(id) for manual timers and recorded calls. Children use separate contexts with parent
identity. Register the workflow as a scenario resource to capture diagnostics and cancel/drain work
around each scenario. Dispose it before its borrowed host. See the
connected workflow guide
for executable examples, DI setup, cleanup deadlines, and supported boundaries.
Call workflow.WithSerialization() before scheduling to check workflow payloads with the SDK JSON
converter, or supply your application's DataConverter. Inputs, activity/child results, events,
final results, and metadata then cross serialized boundaries; received objects are independent.
Direct assignment remains the default. See the connected workflow guide for snapshot timing and
conversion failure behavior.
Call workflow.WithRetries() to simulate SDK retry policies or handlers with manual time and a
finite attempt limit. workflow.Attempts records actual activity/child attempts, and
TestDurableTaskSequence<TResult> supplies ordered failures and results. Retries remain opt-in;
see the retry guide.
Entity tests can attach TestOrchestrationEntityFeature to record orchestrator calls and signals,
or use client.Entities for signal and typed metadata fixtures. TestEntityOperation,
TestEntityContext, and TestEntityState execute real SDK entity implementations explicitly
against serialized state. Signals do not deliver automatically, and local lock markers do not
provide distributed locking. See the
entity guide.
Durable orchestrators can use TestOrchestrationContext to record activity scheduling and dispatch
each call to a real activity instance:
var activity = new CreateOrderActivity(dependency);
var context = new TestOrchestrationContext(async call =>
call.ActivityName switch
{
nameof(CreateOrderActivity) =>
await activity.RunAsync((CreateOrderRequest)call.Input!),
_ => throw new InvalidOperationException($"Unexpected activity '{call.ActivityName}'."),
});
var result = await orchestrator.RunAsync(context);
Assert.Equal(nameof(CreateOrderActivity), context.ActivityCalls.Single().ActivityName);
Orchestration controls
Use WithInput(request) and WithInstanceId("parent-42") to configure orchestration input and identity.
GetInput<T>() returns the retained typed value without serialization.
Timers use manual time starting at DateTime.UnixEpoch. Drive CurrentUtcDateTime and due timers
with AdvanceTimeTo(utcDateTime) or AdvanceTimeBy(duration). Raise events with
RaiseEvent(name, payload); events are buffered and delivered once in FIFO order, matching names
case-insensitively. Timer and event waits support cancellation, and event timeout overloads use simulated time.
Configure SubOrchestratorHandler to dispatch child calls and inspect SubOrchestrationCalls afterward.
The handler can invoke a real child orchestrator with its own test context. SendEvent records
SentEvents and delivers events locally when targeting the current instance ID.
WithReplayState(true) controls IsReplaying for replay branches and log suppression. Logging is
silent by default; supply a caller-owned logger factory with WithLoggerFactory(factory) before
creating replay-safe loggers to inspect output.
Default stubs and fluent overrides
new TestOrchestrationContext() returns typed default values for activity and child calls. Override
dispatch with WithActivityHandler(handler) and WithSubOrchestratorHandler(handler).
Use WithActivityHandler("ActivityName", (name, input) => ...) to route a specific activity.
Names match case-sensitively; named registrations take precedence over the fallback, and registering
the same name again replaces its handler for future calls. All calls are still recorded and type-checked.
Metadata defaults to TestOrchestrator, no parent, an empty version, and empty read-only properties.
Override it with WithName, WithParent, WithVersion, and WithProperties.
Entity calls return typed defaults, signals complete, and local lock scopes update critical-section
markers. Use WithEntities(feature) to provide custom behavior. NewGuid() generates a repeatable
per-instance sequence, overridable with WithGuidGenerator. Version comparison is ordinal by default;
WithVersionComparer can supply another ordering.
SetCustomStatus retains CustomStatus. ContinueAsNew records copied options in
ContinueAsNewRequests without restarting or changing current input, time, version, or events.
Use WithCustomStatus, WithCustomStatusHandler, and WithContinueAsNewHandler to configure or observe these stubs.
Limitations
Standalone orchestration contexts do not implement durable history, automatic replay, persistence, retries, child-instance lifecycle management, or remote event delivery. Connected workflows explicitly dispatch children and events, with opt-in retry and serialization checks as described above; they still do not provide production persistence or replay. Entity defaults do not implement state or distributed locking; GUID sequences do not reproduce the runtime algorithm, and continuation requests do not restart execution.
Documentation
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.Azure.Functions.Worker.Core (>= 2.52.0)
- Microsoft.Azure.Functions.Worker.Extensions.Http (>= 3.3.0)
- Microsoft.Azure.Functions.Worker.Extensions.Timer (>= 4.3.1)
- Microsoft.DurableTask.Abstractions (>= 1.26.0)
- Microsoft.DurableTask.Client (>= 1.24.1)
- XBullet.EasyTesting (>= 1.3.0)
-
net8.0
- Microsoft.Azure.Functions.Worker.Core (>= 2.52.0)
- Microsoft.Azure.Functions.Worker.Extensions.Http (>= 3.3.0)
- Microsoft.Azure.Functions.Worker.Extensions.Timer (>= 4.3.1)
- Microsoft.DurableTask.Abstractions (>= 1.26.0)
- Microsoft.DurableTask.Client (>= 1.24.1)
- XBullet.EasyTesting (>= 1.3.0)
-
net9.0
- Microsoft.Azure.Functions.Worker.Core (>= 2.52.0)
- Microsoft.Azure.Functions.Worker.Extensions.Http (>= 3.3.0)
- Microsoft.Azure.Functions.Worker.Extensions.Timer (>= 4.3.1)
- Microsoft.DurableTask.Abstractions (>= 1.26.0)
- Microsoft.DurableTask.Client (>= 1.24.1)
- XBullet.EasyTesting (>= 1.3.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.3.0 | 0 | 10/22/2026 |
| 1.2.1 | 49 | 10/21/2026 |
| 1.1.0 | 110 | 10/10/2026 |
| 1.0.19 | 99 | 10/5/2026 |
| 1.0.18 | 102 | 10/4/2026 |
| 1.0.17 | 95 | 10/1/2026 |
| 1.0.16 | 102 | 9/30/2026 |
| 1.0.15 | 104 | 9/29/2026 |
| 1.0.14 | 102 | 9/27/2026 |
| 1.0.13 | 104 | 9/26/2026 |
| 1.0.12 | 100 | 9/25/2026 |
| 1.0.11 | 104 | 9/24/2026 |
| 1.0.9 | 97 | 9/24/2026 |
| 1.0.8 | 106 | 9/21/2026 |
| 1.0.7 | 98 | 9/19/2026 |
| 1.0.6 | 111 | 9/18/2026 |
| 1.0.5 | 94 | 9/18/2026 |
| 1.0.4 | 93 | 9/15/2026 |
| 1.0.3 | 100 | 9/15/2026 |
| 0.2.0 | 101 | 9/15/2026 |