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

如何在C# Xunit中模拟静态接口?解决PerformanceLogger空引用异常

问题解决:PerformanceLogger静态TelemetryClient未赋值导致测试报错

问题根源

你的PerformanceLogger类中MyTelemetryClient是静态属性,属于类级别的全局状态。测试代码里虽然创建了Mock<IMyTelemetryClient>实例,但没有将该实例赋值给PerformanceLogger.MyTelemetryClient,导致调用Dispose时触发InvalidOperationException。

另外还有一个细节问题:你在测试中对AddEvent的Setup参数是Dictionary<string, string>类型,但实际Dispose方法里调用的是两个string参数的重载,参数类型不匹配会导致后续验证失败。


解决方案1:修复现有静态属性的测试逻辑

通过给静态属性赋值并做测试隔离,避免影响其他测试用例:

public class PerformanceLoggerTests : IDisposable
{
    private readonly Mock<IMyTelemetryClient> _myClient;

    public PerformanceLoggerTests()
    {
        _myClient = new Mock<IMyTelemetryClient>();
        // 初始化静态属性
        PerformanceLogger.MyTelemetryClient = _myClient.Object;
    }

    [Fact]
    public void Test_PerformanceLogger()
    {
        // 匹配实际调用的参数类型(两个string)
        _myClient.Setup(x => x.AddEvent(It.IsAny<string>(), It.IsAny<string>()));
        
        var service = new PerformanceLogger();

        // 执行Dispose
        service.Dispose();

        // 验证方法是否按预期被调用
        _myClient.Verify(x => x.AddEvent("N/A", "someTest"), Times.Once);
    }

    // 测试结束后重置静态属性,避免污染其他测试
    public void Dispose()
    {
        PerformanceLogger.MyTelemetryClient = null;
    }
}

解决方案2:重构为构造函数注入(推荐)

静态依赖会导致测试隔离性差、维护成本高,建议将MyTelemetryClient改为实例属性,通过构造函数注入依赖:

修改PerformanceLogger类

public class PerformanceLogger : IDisposable
{
    private readonly IMyTelemetryClient _myTelemetryClient;

    // 构造函数注入,确保实例创建时依赖已就绪
    public PerformanceLogger(IMyTelemetryClient myTelemetryClient)
    {
        _myTelemetryClient = myTelemetryClient ?? throw new ArgumentNullException(nameof(myTelemetryClient));
    }

    public void Dispose()
    {
        _myTelemetryClient.AddEvent("N/A", "someTest");
    }
}

对应测试代码

public class PerformanceLoggerTests
{
    private readonly Mock<IMyTelemetryClient> _myClient;

    public PerformanceLoggerTests()
    {
        _myClient = new Mock<IMyTelemetryClient>();
    }

    [Fact]
    public void Test_PerformanceLogger()
    {
        _myClient.Setup(x => x.AddEvent("N/A", "someTest"));
        
        // 直接通过构造函数传入Mock实例
        var service = new PerformanceLogger(_myClient.Object);

        service.Dispose();

        _myClient.Verify(x => x.AddEvent("N/A", "someTest"), Times.Once);
    }
}

内容的提问来源于stack exchange,提问作者Mukesh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 23:25:16