Skip to main content

policy-emulator-testing

Conventions and patterns for writing gateway emulator policy handler tests in the Azure API Management policy toolkit. Use this skill when creating or modifying test files in test/Test.Testing/Emulator/Policies/.

Quellinformationen

Repository
Azure/azure-api-management-policy-toolkit
Letzte Quellaktivität
8. März 2026 um 18:53
Erkannte Sprache von SKILL.md
Englisch
Sterne
96
Forks
37

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
policy-emulator-testing
description
Conventions and patterns for writing gateway emulator policy handler tests in the Azure API Management policy toolkit. Use this skill when creating or modifying test files in test/Test.Testing/Emulator/Policies/.
# Policy Emulator Testing Patterns This skill describes how to write tests for gateway emulator policy handlers in the Azure API Management policy toolkit. ## Test File — `test/Test.Testing/Emulator/Policies/{PolicyName}Tests.cs` ### File Template ```csharp // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. namespace Test.Emulator.Emulator.Policies; [TestClass] public class {PolicyName}Tests { // Inner document class implementing IDocument class Simple{PolicyName} : IDocument { public void Inbound(IInboundContext context) { context.{PolicyName}(new {PolicyName}Config { // config properties }); } public void Outbound(IOutboundContext context) { } public void Backend(IBackendContext context) { } public void OnError(IOnErrorContext context) { } } [TestMethod] public void Should{ExpectedBehavior}() { // Arrange var test = new Simple{PolicyName}().AsTestDocument(); // Act test.RunInbound(); // Assert (using FluentAssertions) test.Context.{assertion}; } } ``` ### Key Conventions - **Namespace**: `Test.Emulator.Emulator.Policies` (matches existing test convention) - **Class name**: `{PolicyName}Tests` - **Framework**: MSTest (`[TestClass]`, `[TestMethod]`) - **Assertions**: FluentAssertions - **Test document creation**: `new SimpleDocument().AsTestDocument()` extension method (or `new TestDocument(new SimpleDocument())` — both are equivalent) - **Inner document classes** implement `IDocument` with all four section methods. Unused sections have empty bodies. - **Section execution**: `test.RunInbound()`, `test.RunOutbound()`, `test.RunBackend()`, `test.RunOnError()` ## Required Test Coverage Each policy must have tests covering: ### 1. Basic Execution Create a document with the policy call, run through `TestDocument`, assert context state changes: ```csharp [TestMethod] public void ShouldModifyContextState() { var test = new SimpleSetStatus().AsTestDocument(); test.RunInbound(); test.Context.Response.StatusCode.Should().Be(200); test.Context.Response.StatusReason.Should().Be("OK"); } ``` ### 2. Callback Override Verify that `SetupInbound()` (or appropriate section) `.{PolicyName}().WithCallback(...)` correctly overrides default behavior: ```csharp [TestMethod] public void ShouldExecuteCallback() { var test = new Simple{PolicyName}().AsTestDocument(); test.SetupInbound() .{PolicyName}() .WithCallback((context, config) => { context.Variables["test"] = "value"; }); test.RunInbound(); test.Context.Variables.Should().ContainKey("test") .WhoseValue.Should().Be("value"); } ``` ### 3. Predicate-Based Mock For policies called multiple times with different configs in the same section: ```csharp [TestMethod] public void ShouldSelectCorrectCallback() { var test = new Multi{PolicyName}().AsTestDocument(); test.SetupInbound() .{PolicyName}((ctx, config) => config.SomeProperty == "A") .WithCallback((ctx, cfg) => { /* handle A */ }); test.SetupInbound() .{PolicyName}((ctx, config) => config.SomeProperty == "B") .WithCallback((ctx, cfg) => { /* handle B */ }); test.RunInbound(); // Assert... } ``` ### 4. Pre-configured Context When the handler depends on existing context state: ```csharp [TestMethod] public void ShouldHandleExistingHeaders() { var test = new Simple{PolicyName}().AsTestDocument(); test.Context.Request.Headers["Content-Type"] = ["application/json"]; test.RunInbound(); test.Context.Request.Headers.Should().ContainKey("Content-Type"); } ``` ### 5. Error/Exception Scenarios Not all policies support `.WithError()`. This API is specific to certain mock providers (e.g., `MockAuthenticationManagedIdentityProvider`). For policies without a dedicated error API, simulate errors via callbacks: ```csharp [TestMethod] public void ShouldSimulateError() { var test = new Simple{PolicyName}().AsTestDocument(); test.SetupInbound() .{PolicyName}() .WithCallback((context, config) => { context.Response.StatusCode = 500; context.Response.StatusReason = "Internal Server Error"; throw new FinishSectionProcessingException(); }); test.RunInbound(); test.Context.Response.StatusCode.Should().Be(500); } ``` For authentication policies that have `.WithError()`: ```csharp [TestMethod] public void ShouldThrowOnError() { var test = new SimpleAuthenticationManagedIdentity().AsTestDocument(); test.SetupInbound() .AuthenticationManagedIdentity() .WithError("InternalServerError"); var ex = Assert.ThrowsException<PolicyException>(() => test.RunInbound()); ex.Policy.Should().Be("AuthenticationManagedIdentity"); } ``` ### 6. Multi-Section Tests If the policy is available in multiple sections, add one test per section: ```csharp [TestMethod] public void ShouldWorkInOutboundSection() { var test = new Outbound{PolicyName}().AsTestDocument(); test.RunOutbound(); test.Context.{assertion}; } ``` ## Mock Setup Patterns ### Token Provider Hook (Authentication policies) ```csharp test.SetupInbound() .AuthenticationManagedIdentity() .WithTokenProviderHook((resource, clientId) => $"{resource}{clientId}/token"); ``` ### Return Value (Authentication, Cache) ```csharp test.SetupInbound() .AuthenticationManagedIdentity() .ReturnsToken("mock-token"); ``` ### Cache Store Setup ```csharp test.SetupCacheStore() .WithExternalCacheSetup() .WithExternalCacheValue("key", "test"); test.SetupCacheStore().WithInternalCacheValue("key", "test"); ``` ### Response Example Store (MockResponse) ```csharp var example = new ResponseExample(200, "{ \"ok\": true }", "application/json"); test.SetupResponseExampleStore().Add(test.Context, example); ``` ## Test Infrastructure Tests rely on shared infrastructure that you do not need to modify: - **`TestDocument`** (`src/Testing/TestDocument.cs`) — Wraps an `IDocument` and executes sections through proxies. Catches `FinishSectionProcessingException` gracefully. - **`.AsTestDocument()`** extension method — Creates `TestDocument` from `IDocument`. - **`SetupInbound()`/`SetupOutbound()`/etc.** — Returns `MockPoliciesProvider<TSection>` for fluent mock configuration. - **`GatewayContext`** (`src/Testing/GatewayContext.cs`) — Contains mock request/response, variables, and emulator stores. - **`Usings.cs`** (`test/Test.Testing/Usings.cs`) — Global usings for `FluentAssertions` and `Microsoft.VisualStudio.TestTools.UnitTesting`. ## Build and Test Commands ```bash # Run all emulator tests dotnet test --project test/Test.Testing # Run tests for a specific policy dotnet test --project test/Test.Testing --filter "FullyQualifiedName~{PolicyName}Tests" ```
Auf GitHub ansehen