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

如何为ContinueWith编写单元测试?Xunit+NSubstitute遇IsFaulted覆盖难题

测试Task.IsFaulted分支的Xunit+NSubstitute用例

要覆盖task.IsFaulted分支,核心是让_service.GetProfile(code)返回一个处于Faulted状态的Task,以下是具体实现步骤和测试用例:

1. 明确被测方法结构(假设)

先把业务代码封装到可测试的方法中,示例如下:

public class ProfileHandler
{
    private readonly IProfileService _service;

    public ProfileHandler(IProfileService service)
    {
        _service = service;
    }

    public async Task<object> GetProfileResponse(string code)
    {
        var response = await await _service.GetProfile(code)
            .ContinueWith(async task =>
            {
                if (task.IsFaulted)
                {
                    // 待覆盖的错误分支逻辑,示例返回默认对象
                    return new object();
                }
                // 正常分支逻辑(示例)
                var profile = await task;
                return profile;
            });
        return response;
    }
}

// 定义服务接口
public interface IProfileService
{
    Task<Profile> GetProfile(string code);
}

public class Profile { }

2. 编写Xunit测试用例

通过NSubstitute模拟IProfileService,让GetProfile返回Faulted状态的Task:

using Xunit;
using NSubstitute;

public class ProfileHandlerTests
{
    [Fact]
    public async Task GetProfileResponse_WhenGetProfileFails_ExecutesFaultedBranch()
    {
        // 1. 准备模拟依赖
        var mockService = Substitute.For<IProfileService>();
        // 创建Faulted状态的Task,模拟服务调用失败
        var faultedTask = Task.FromException<Profile>(new InvalidOperationException("模拟服务调用出错"));
        mockService.GetProfile(Arg.Any<string>()).Returns(faultedTask);

        // 2. 实例化被测对象
        var handler = new ProfileHandler(mockService);

        // 3. 执行被测方法
        var result = await handler.GetProfileResponse("test-code");

        // 4. 验证分支逻辑执行结果(根据实际需求调整断言)
        Assert.NotNull(result);
        // 如果错误分支中有其他操作(如日志记录),可在此验证:
        // mockLogger.Received(1).LogError(Arg.Any<Exception>(), Arg.Any<string>());
    }
}

关键说明

  • 用Task.FromException<TResult>()直接创建Faulted状态的Task,这是触发task.IsFaulted的核心。
  • 无需手动抛出异常,GetProfile返回的Task本身已处于错误状态,ContinueWith会自动检测到task.IsFaulted为true。
  • 如果GetProfile返回无返回值的Task(而非Task<T>),则用Task.FromException(new Exception(...))创建Faulted Task。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 00:20:21