AzureFunctions.TestFramework.Durable
0.11.1
See the version list below for details.
dotnet add package AzureFunctions.TestFramework.Durable --version 0.11.1
NuGet\Install-Package AzureFunctions.TestFramework.Durable -Version 0.11.1
<PackageReference Include="AzureFunctions.TestFramework.Durable" Version="0.11.1" />
<PackageVersion Include="AzureFunctions.TestFramework.Durable" Version="0.11.1" />
<PackageReference Include="AzureFunctions.TestFramework.Durable" />
paket add AzureFunctions.TestFramework.Durable --version 0.11.1
#r "nuget: AzureFunctions.TestFramework.Durable, 0.11.1"
#:package AzureFunctions.TestFramework.Durable@0.11.1
#addin nuget:?package=AzureFunctions.TestFramework.Durable&version=0.11.1
#tool nuget:?package=AzureFunctions.TestFramework.Durable&version=0.11.1
AzureFunctions.TestFramework.Durable
Fake-backed Durable Functions test helpers for the Azure Functions Test Framework. Includes ConfigureFakeDurableSupport(...), FakeDurableTaskClient, direct activity invocation, fake orchestration scheduling, sub-orchestrators, external events, and HTTP status polling helpers.
No real Durable Task runtime or external storage (Azure Storage / Netherite / MSSQL) is needed.
Why fake-backed?
The real Durable Task execution engine relies on external storage and the Durable Task Framework host, neither of which runs inside the test framework's in-process worker. ConfigureFakeDurableSupport(...) registers a FakeDurableTaskClient and companion types that intercept [DurableClient] binding resolution at the DI level, letting starter functions, orchestrators, activities, and sub-orchestrators execute fully in-process.
Setup
using AzureFunctions.TestFramework.Core;
using AzureFunctions.TestFramework.Durable;
_testHost = await new FunctionsTestHostBuilder()
.WithFunctionsAssembly(typeof(MyDurableFunction).Assembly)
.ConfigureFakeDurableSupport(provider =>
{
// Register orchestration runners
provider.AddOrchestration<string>("MyOrchestrator", ctx => MyOrchestratorFunction.RunAsync(ctx));
})
.BuildAndStartAsync();
Coverage
[DurableClient] DurableTaskClientinjection (both direct gRPC and ASP.NET Core integration paths)- Direct activity invocation via
IFunctionsTestHost.InvokeActivityAsync<TResult>(...) - Fake orchestration scheduling and activity execution
- Sub-orchestrator execution via
TaskOrchestrationContext.CallSubOrchestratorAsync<TResult>() - Custom status via
SetCustomStatus(...)andOrchestrationMetadata.ReadCustomStatusAs<T>() - External events: both wait-then-raise and buffered raise-before-wait flows
FunctionsDurableClientProviderresolution fromFunctionsTestHost.Services
Example
public class DurableFunctionTests : IAsyncLifetime
{
private IFunctionsTestHost _testHost;
public async Task InitializeAsync()
{
_testHost = await new FunctionsTestHostBuilder()
.WithFunctionsAssembly(typeof(OrderOrchestrator).Assembly)
.WithHostBuilderFactory(Program.CreateHostBuilder)
.ConfigureFakeDurableSupport(provider =>
{
provider.AddOrchestration<OrderResult>("OrderOrchestrator",
ctx => OrderOrchestratorFunction.RunAsync(ctx));
provider.AddActivity<string, OrderResult>("ProcessOrder",
input => new OrderResult { Success = true, OrderId = input });
})
.BuildAndStartAsync();
}
[Fact]
public async Task StartOrder_StartsOrchestration_AndCompletes()
{
// Start via HTTP starter function
using var client = _testHost.CreateHttpClient();
var response = await client.PostAsync("/api/orders/start", JsonContent.Create(new { orderId = "123" }));
response.EnsureSuccessStatusCode();
var instanceId = await response.Content.ReadAsStringAsync();
// Resolve the durable client and check status
var durableClient = _testHost.Services
.GetRequiredService<FunctionsDurableClientProvider>()
.GetClient();
var metadata = await durableClient.GetInstanceAsync(instanceId);
Assert.Equal(OrchestrationRuntimeStatus.Completed, metadata!.RuntimeStatus);
}
[Fact]
public async Task ProcessOrder_Activity_ReturnsResult()
{
// Invoke activity directly
var result = await _testHost.InvokeActivityAsync<OrderResult>("ProcessOrder", "order-123");
Assert.True(result.Success);
Assert.Equal("order-123", result.OrderId);
}
[Fact]
public async Task OrderOrchestrator_WithExternalEvent_Completes()
{
var durableClient = _testHost.Services
.GetRequiredService<FunctionsDurableClientProvider>()
.GetClient() as FakeDurableTaskClient;
var instanceId = await durableClient!.ScheduleNewOrchestrationInstanceAsync("OrderOrchestrator", "order-123");
// Raise external event to unblock orchestrator
await durableClient.RaiseEventAsync(instanceId, "ApprovalReceived", true);
var metadata = await durableClient.GetInstanceAsync(instanceId);
Assert.Equal(OrchestrationRuntimeStatus.Completed, metadata!.RuntimeStatus);
}
public async Task DisposeAsync()
{
await _testHost.StopAsync();
_testHost.Dispose();
}
}
References
License
MIT
| 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 was computed. 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
- AzureFunctions.TestFramework.Core (>= 0.11.1)
- Microsoft.Azure.Functions.Worker.Extensions.DurableTask (>= 1.16.2)
-
net8.0
- AzureFunctions.TestFramework.Core (>= 0.11.1)
- Microsoft.Azure.Functions.Worker.Extensions.DurableTask (>= 1.16.2)
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 |
|---|---|---|
| 0.12.0 | 84 | 4/20/2026 |
| 0.11.2 | 98 | 4/14/2026 |
| 0.11.1 | 86 | 4/13/2026 |
| 0.11.0 | 99 | 4/13/2026 |
| 0.10.0 | 96 | 4/11/2026 |
| 0.9.0 | 90 | 4/8/2026 |
| 0.8.0 | 91 | 4/7/2026 |
| 0.7.1 | 87 | 4/7/2026 |
| 0.7.0 | 84 | 4/7/2026 |
| 0.6.0 | 100 | 4/7/2026 |
| 0.5.0 | 95 | 4/2/2026 |
| 0.4.1 | 89 | 4/1/2026 |
| 0.4.0 | 91 | 4/1/2026 |
| 0.3.0 | 89 | 4/1/2026 |
| 0.2.1 | 93 | 3/17/2026 |
| 0.2.0 | 89 | 3/17/2026 |