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

如何Mock参数为异步函数的服务依赖?附代码示例

如何Mock参数为Func<CancellationToken, IServiceProvider, Task>的QueueBackgroundWorkItem方法

你要Mock的QueueBackgroundWorkItem方法接收一个Func<CancellationToken, IServiceProvider, Task>类型的委托参数,结合Moq框架,这里提供几种实用的处理方式:


1. 匹配任意委托参数(基础用法)

如果只需要验证方法被调用过,不需要关心具体传入的委托逻辑,可以直接用It.IsAny<>匹配任意符合类型的参数:

Mock<IBackgroundTaskQueue> _mock = new Mock<IBackgroundTaskQueue>();

// Setup void方法,无需返回值(原方法是void,不要加Returns(Task.CompletedTask))
_mock.Setup(x => x.QueueBackgroundWorkItem(It.IsAny<Func<CancellationToken, IServiceProvider, Task>>()))
     .Verifiable();

// 执行被测试代码后,验证方法是否被调用
_mock.Verify(x => x.QueueBackgroundWorkItem(It.IsAny<Func<CancellationToken, IServiceProvider, Task>>()), Times.Once);

2. 捕获传入的委托并执行(验证委托逻辑)

如果需要验证传入的委托逻辑是否正确,或者要手动执行委托来测试其行为,可以通过Callback捕获传入的委托:

Mock<IBackgroundTaskQueue> _mock = new Mock<IBackgroundTaskQueue>();
Func<CancellationToken, IServiceProvider, Task> capturedWorkItem = null;

// 捕获传入的委托
_mock.Setup(x => x.QueueBackgroundWorkItem(It.IsAny<Func<CancellationToken, IServiceProvider, Task>>()))
     .Callback<Func<CancellationToken, IServiceProvider, Task>>(workItem => 
     {
         capturedWorkItem = workItem;
     });

// 执行被测试代码,触发QueueBackgroundWorkItem调用

// 手动执行捕获到的委托,传入模拟的依赖
var mockServiceProvider = new Mock<IServiceProvider>().Object;
var cancellationToken = CancellationToken.None;
await capturedWorkItem(cancellationToken, mockServiceProvider);

// 验证方法调用次数
_mock.Verify(x => x.QueueBackgroundWorkItem(It.IsAny<Func<CancellationToken, IServiceProvider, Task>>()), Times.Once);

3. 匹配特定委托(自定义判断逻辑)

如果需要仅匹配满足特定条件的委托,可以用It.Is<>()添加自定义校验逻辑:

Mock<IBackgroundTaskQueue> _mock = new Mock<IBackgroundTaskQueue>();

_mock.Setup(x => x.QueueBackgroundWorkItem(It.Is<Func<CancellationToken, IServiceProvider, Task>>(func => 
{
    // 这里添加自定义判断逻辑,比如验证委托是否依赖某个特定服务
    // 示例:假设委托需要从IServiceProvider获取ILogger服务
    var testProvider = new Mock<IServiceProvider>().Object;
    try
    {
        // 尝试执行委托的部分逻辑来判断
        var task = func(CancellationToken.None, testProvider);
        return task != null;
    }
    catch
    {
        return false;
    }
})))
.Verifiable();

注意:原方法QueueBackgroundWorkItem是void类型,不要调用.Returns(Task.CompletedTask),Moq中Setup void方法不需要设置返回值。

内容的提问来源于stack exchange,提问作者M Javad Salehi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 07:47:38