c# - 如何使用 ReceiveAsync 测试 Akka.NET actor 中的异步异常

标签 c# testing xunit akka.net

我的应用程序和单元测试中都有一个 try/catch block 。我正在尝试创建一个测试来捕获在我的 Actor 中抛出的异常。通过代码进行调试时,我抛出了异常,但在我的测试中,我从未收到异常。

应用:

public class FooActor : ReceiveActor {
    private readonly IFooService fooService;
    private readonly IChildActorFactory childCreatorFactory;
    private IActorRef barActor;

    public FooActor(IFooService fooService, IChildActorFactory childCreatorFactory) {   
        this.fooService = fooService;
        this.childCreatorFactory = childCreatorFactory;

        ReceiveAsync<bool>(async (x) => await StartAsync(x).ConfigureAwait(false));
    }

    protected override void PreStart() {
        barActor = childCreatorFactory.Create<BarActor>(Context, "BarActor");
    }

    public async Task StartAsync(bool start) {
        try {
            if (start) {
                var fooInformation = await fooService.GetInformationAsync().ConfigureAwait(false);

                if (fooInformation != null) {
                    barActor.Tell(fooInformation);
                }
            }
        } catch (Exception exception) {
            throw new Exception($"Unhandled exception. Actor {Self.Path.Name};", exception);
        }
    }
}

测试:

[Fact]
public void StartAsync_ThrowsException_ExceptionThrown() {
    using (var mock = AutoMock.GetLoose()) {
        //Arrange
        Sys.UseAutofac(mock.Container);
        var mockChildActorFactory = mock.Mock<IChildActorFactory>();
        var mockBarService = mock.Mock<IBarService>();

        mockBarService.Setup(x => x.GetInformationAsync()).Throws(new Exception());

        var props = Props.Create(() => new FooActor(mockBarService.Object, mockChildActorFactory.Object));

        var fooActorName = "FooActor";
        var fooActor = new TestActorRef<FooActor>(Sys, props, null, fooActorName);

        try {
            // Act
            fooActor.Receive(true);
        } catch (Exception exception) {
            // Assert
            Assert.Equal($"Unhandled Exception. Actor { fooActorName }.", exception.Message);
        }
    }
}

最佳答案

问题出在 ReceiveAsync 方法中的异步/等待运算符中:

ReceiveAsync<bool>(async (x) => await StartAsync(x).ConfigureAwait(false));

当执行上下文到达等待操作时,它只是在线程池(简化)中启动任务并返回给调用者。 IE。什么时候

fooActor.Receive(true);

已完成,StartAsync(x) 的实际任务可能尚未开始。因此,当抛出实际异常时,您的测试已经完成,没有任何异常。

关于c# - 如何使用 ReceiveAsync 测试 Akka.NET actor 中的异步异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58511959/

相关文章:

C# - 如何检查是否需要构造一个类型的对象?

c# - Linq 查询不返回值

visual-studio - 无法在 Visual Studio 2017 上运行 Xunit 测试

c# - 是否可以为使用 Xamarin.Essentials : Geolocation API? 的函数创建单元测试

c# - 解析和序列化

c# - FullCalendar,如何允许用户编辑/删除事件并将其从数据库中删除?

c# - 如何在 C# 中进行性能测试

ruby - 在 rails 3.0.1 中测试自定义路由不起作用,还是我?

testing - 移动和桌面应用程序测试的差异

c# - 使用 Documentformat.OpenXML 在 C# 中验证 Excel 文件