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

能否将Mock对象的调用次数作为参数传入单元测试类方法?

问题解决:单元测试方法扩展为接收Mock预期调用次数参数

编译失败的核心原因是:[InlineData]要求传入的参数必须是编译时常量,而Times.Never、Times.Once是Times结构体的运行时实例,不属于编译时常量范畴,因此无法直接用于InlineData。

以下两种方案可以实现你的需求:

方案1:使用MemberData提供测试数据

MemberData支持返回任意类型的测试数据,完美适配Times类型的传递需求:

public class YourTestClass
{
    // 定义静态测试数据源
    public static IEnumerable<object[]> VerificationTestData()
    {
        yield return new object[] { "", Times.Never };
        yield return new object[] { "test", Times.Once };
    }

    [Theory]
    [MemberData(nameof(VerificationTestData))]
    public async Task PostAsync_SendAsync_VerifyOnce(string id, Times outcome)
    {
        var mockClients = new Mock<IHubClients>();
        // ... 你的业务逻辑与Mock配置代码 ...
        mockClients.Verify(clients => clients.Client(id), outcome);
    }
}

注意:将async void改为async Task是单元测试的最佳实践——async void会导致测试框架无法正确等待异步操作完成,可能出现测试结果不准确的问题。

方案2:通过枚举/整数映射转换为Times

如果更倾向于使用InlineData的简洁性,可以先传入简单的常量类型,再在测试方法内转换为Times实例:

枚举映射方式

// 定义预期调用次数枚举
public enum ExpectedCallFrequency
{
    Never,
    Once
}

[Theory]
[InlineData("", ExpectedCallFrequency.Never)]
[InlineData("test", ExpectedCallFrequency.Once)]
public async Task PostAsync_SendAsync_VerifyOnce(string id, ExpectedCallFrequency frequency)
{
    var mockClients = new Mock<IHubClients>();
    // ... 你的业务逻辑与Mock配置代码 ...

    // 将枚举转换为Times实例
    Times outcome = frequency switch
    {
        ExpectedCallFrequency.Never => Times.Never,
        ExpectedCallFrequency.Once => Times.Once,
        _ => throw new ArgumentOutOfRangeException(nameof(frequency))
    };

    mockClients.Verify(clients => clients.Client(id), outcome);
}

整数映射方式

[Theory]
[InlineData("", 0)]
[InlineData("test", 1)]
public async Task PostAsync_SendAsync_VerifyOnce(string id, int expectedCallCount)
{
    var mockClients = new Mock<IHubClients>();
    // ... 你的业务逻辑与Mock配置代码 ...

    Times outcome = expectedCallCount == 0 ? Times.Never : Times.Exactly(expectedCallCount);
    mockClients.Verify(clients => clients.Client(id), outcome);
}

两种方案都能实现你的测试需求:空id时验证调用从未发生,有效id时验证调用发生一次。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 02:55:16