Extract product-agnostic workflow engine from Ablera.Serdica.Workflow into standalone StellaOps.Workflow.* libraries targeting net10.0. Libraries (14): - Contracts, Abstractions (compiler, decompiler, expression runtime) - Engine (execution, signaling, scheduling, projections, hosted services) - ElkSharp (generic graph layout algorithm) - Renderer.ElkSharp, Renderer.ElkJs, Renderer.Msagl, Renderer.Svg - Signaling.Redis, Signaling.OracleAq - DataStore.MongoDB, DataStore.PostgreSQL, DataStore.Oracle WebService: ASP.NET Core Minimal API with 22 endpoints Tests (8 projects, 109 tests pass): - Engine.Tests (105 pass), WebService.Tests (4 E2E pass) - Renderer.Tests, DataStore.MongoDB/Oracle/PostgreSQL.Tests - Signaling.Redis.Tests, IntegrationTests.Shared Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Tutorial 9: Testing Your Workflow
Write unit tests for workflows using RecordingSerdicaLegacyRabbitTransport and TechnicalStyleWorkflowTestHelpers.
Test Setup Pattern
- Create a recording transport with pre-configured responses
- Build a test service provider via
TechnicalStyleWorkflowTestHelpers.CreateServiceProvider - Resolve
WorkflowRuntimeServicefrom DI - Call
StartWorkflowAsyncwith test payload - Assert: tasks created, transport calls made, state values correct
- Optionally complete tasks and verify downstream behavior
What to Test
| Scenario | Approach |
|---|---|
| Workflow starts correctly | Assert single open task after start |
| Service calls made in order | transport.Invocations.Select(x => x.Command).Should().Equal(...) |
| Rejection flow | Complete task with "answer": "reject", verify cancel call |
| Approval flow | Complete with "answer": "approve", verify conversion calls |
| Operations failure re-opens task | Check same task re-appears after operations return passed: false |
| Sub-workflow creates child tasks | Query tasks by child workflow name |
| Business reference set | startResponse.BusinessReference.Key.Should().Be(...) |