You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何测试Serilog的DiagnosticContext是否设置了正确的值?

单元测试验证Serilog DiagnosticContext 属性的方案

DiagnosticContext 未提供公开API直接读取内部存储的属性,属性仅会在日志事件输出时被附加到事件上,你可以通过捕获日志事件的方式做断言,具体实现如下:

步骤1:安装依赖包

使用内存Sink捕获日志事件,安装NuGet包:Serilog.Sinks.InMemory

步骤2:编写测试逻辑

using Serilog;
using Serilog.Sinks.InMemory;
using Xunit; // 可替换为你使用的单元测试框架

public class DiagnosticContextTests
{
    [Fact]
    public void Verify_DiagnosticContext_Properties_Set_Correctly()
    {
        // 1. 配置Serilog,启用DiagnosticContext富集,用内存Sink捕获日志
        var inMemorySink = new InMemorySink();
        Log.Logger = new LoggerConfiguration()
            .Enrich.FromDiagnosticContext() // 必须配置,否则属性不会附加到日志
            .WriteTo.Sink(inMemorySink)
            .CreateLogger();

        try
        {
            // 2. 模拟业务代码中设置DiagnosticContext的逻辑
            using (Serilog.Context.DiagnosticContext.PushProperty("OrderId", 12345))
            {
                Serilog.Context.DiagnosticContext.Set("UserName", "ZhangSan");
                
                // 必须输出一条日志,触发属性附加到日志事件
                Log.Information("业务操作执行完成");
            }

            // 3. 捕获日志事件,断言属性
            var loggedEvent = inMemorySink.LogEvents.Single();
            
            // 断言OrderId属性存在且值正确
            Assert.True(loggedEvent.Properties.TryGetValue("OrderId", out var orderIdVal));
            Assert.Equal("12345", orderIdVal.ToString().Trim('"'));
            
            // 断言UserName属性存在且值正确
            Assert.True(loggedEvent.Properties.TryGetValue("UserName", out var userNameVal));
            Assert.Equal("ZhangSan", userNameVal.ToString().Trim('"'));
        }
        finally
        {
            Log.CloseAndFlush();
        }
    }
}

备选方案(不推荐,依赖Serilog内部实现)

如果你不想输出测试日志,可以通过反射读取DiagnosticContext的内部存储,该方案可能在Serilog版本更新后失效:

using System.Reflection;
using Serilog.Context;

// 读取当前DiagnosticContext的内部属性集合
var currentContext = typeof(DiagnosticContext)
    .GetField("_current", BindingFlags.NonPublic | BindingFlags.Static)
    ?.GetValue(null);

var properties = currentContext?.GetType()
    .GetField("_properties", BindingFlags.NonPublic | BindingFlags.Instance)
    ?.GetValue(currentContext) as IEnumerable<KeyValuePair<string, object>>;

// 直接断言properties中的值即可

测试diagnosticContext
内容的提问来源于stack exchange,提问作者Yifan Ai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 18:18:00