-
Notifications
You must be signed in to change notification settings - Fork 0
⭐ Testing
Framework: MSTest.Sdk on .NET's newer Microsoft.Testing.Platform (MTP) runner — already pinned in global.json from the original SDK research, not a new choice. MTP is a genuinely different CLI surface from the older VSTest-based dotnet test (its own --help says so directly) — coverage and TRX reporting are both built into the runner itself, confirmed against a real scratch project rather than assumed.
Testing is no longer a separate end-of-migration phase. tests/eShop.ServiceDefaults.UnitTests (33 tests), tests/EventBus.UnitTests (16 tests), tests/EventBusRabbitMQ.UnitTests (17 tests), and tests/IntegrationEventLogEF.UnitTests (17 tests) — 83 tests total — were all added and grown to full coverage of their applicable files. Going forward, every project gets its own test project in the same unit of work as its source files — src/Shared/ included, despite not being a .csproj project itself. Not every file needs one, though: EventBus's IEventBus/IEventBusBuilder are pure interfaces with zero behavior, so nothing to assert at runtime.
Decorators turned out to matter for testability, not just design: ResilientEventBusDecorator/TelemetryEventBusDecorator both wrap any IEventBus, so their tests use a fake inner bus — no RabbitMQ broker needed. That's what finally let the Polly retry fix get verified end-to-end, closing a gap that had sat unproven since the fix landed (previously only confirmed by reflecting the Polly.Core assembly).
Three patterns worth knowing:
-
InternalsVisibleToforinternalclasses worth testing directly, rather than reflection (brittle) or skipping coverage — used onOpenApiOptionsExtensions, which isinternalend-to-end. -
NSubstitute(already centrally pinned, upstream's ownOrdering.UnitTestsuses it too) for behavior only reachable through a DI/HTTP pipeline —HttpClientExtensions's bearer-token-injecting handler is a private nested class, only exercisable through its publicAddAuthTokensurface plus a mockedIAuthenticationService. -
Extracting a reflection-coupled seam into a pure function, not mocking around it —
IntegrationEventLogService<TContext>'s event-type resolution was hard-wired toAssembly.GetEntryAssembly(), which made its collision-detection branch (two event types sharing a short name) untestable in isolation. Moved into its ownIntegrationEventTypeResolverclass taking plainIEnumerable<Type>/IReadOnlyDictionary<string, Type>inputs instead — the reflection dependency stays at the one real call site, the logic worth testing becomes pure and testable with hand-built inputs.
Tracked, not solved: wanted one combined HTML report across every test project; MTP's --report-html produces one file per project instead (confirmed via a real 2-project scratch solution). The real fix (microsoft/testfx#10529) merged 2026-08-09 but hasn't shipped in a NuGet release yet — Dependabot already tracks the package individually, so no new tooling is needed to know when it does.
Full detail in todo.md's "Testing strategy" section and docs/architecturedesign.md Section 11.