繁体   English   中英

Moq 在调用 Task.WhenAll 的任务之一中抛出异步异常

[英]Moq Throw async exception in one of tasks in call to Task.WhenAll

我有许多任务要传递给 Task.WhenAll 调用。 在我的测试中,我正在设置第一个抛出异常的任务,但是我对 Tasks.WhenAll 的调用并未针对所有任务完成,并且在抛出异常时立即中断。 我的假设是当调用 Tasks.WhenAll 时所有任务都将完成并返回,所以我认为 Moq 无法区分抛出异步和非异步异常。

我希望能够允许所有任务运行,一旦所有任务都完成,我想抓住有问题的任务并提取它们的异常并采取相应的行动。 我的实现是否正确? Moq 是否无法应对,或者我是否必须修复我的实施并且问题不在于 Moq?

public async Task StartAsync(TextWriter log)
{
    log = TextWriter.Synchronized(log);
    var processorTaks = _processors.Select(x => x.StartAsync(log)).ToList();
    Task.WhenAll(processorTaks).Wait();
    var innerExceptions = processorTaks.Where(x => x.Exception != null)
        .Select(x => x.Exception.InnerException)
        .ToList();
    if (innerExceptions.Any())
    {
        innerExceptions.AddRange(_processors.SelectMany(x => x.NotifierException).ToList());
        var formattedExceptions = innerExceptions
            .Select(ex => $"{ex.Message}<\br>{ex.StackTrace}")
            .Distinct();
        IEnumerable<Task> sendEmailTaks = _alertEmailAddresses
            .Split('|')
            .Select(
                x =>
                    _smtpClient.SendMailAsync($"Notifications failed with {innerExceptions.Count()} exceptions",
                        string.Join("<\br>", formattedExceptions), x));
        var retry = _createWebRetry();
        await retry.RetryAsync(() => Task.WhenAll(sendEmailTaks), CancellationToken.None);
    }
}

我的处理器设置:

FirstProcessor.Setup(x => x.StartAsync(It.IsAny<TextWriter>())).Throws(new Exception("some exception happened."));
SecondProcessor.Setup(x => x.StartAsync(It.IsAny<TextWriter>())).Returns(Task.FromResult(default(object)));

正如布鲁诺正确指出的那样,问题在于模拟的StartAsync同步抛出异常,而不是返回错误的任务。

但是,正确的代码不能使用new Task (这将导致挂起,因为任务从未启动)。 相反,使用Task.FromException

FirstProcessor.Setup(x => x.StartAsync(It.IsAny<TextWriter>())).Returns(
    Task.FromException(new Exception("some exception happened."))
);

Task.WhenAll将调用StartAsync ,这将抛出。 在调用线程上抛出异常。 在创建任务之前。

您希望StartAsync返回一个Task

firstProcessor.Setup(x => x.StartAsync(It.IsAny<TextWriter>())).Returns(new Task(() => { throw new Exception("err"); }));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM