簡體   English   中英

如何使用 ReceiveAsync 在 Akka.NET Actor 中測試異步異常

[英]How to test async exceptions in Akka.NET actor with a ReceiveAsync

我的應用程序和單元測試中都有一個 try/catch 塊。 我正在嘗試創建一個測試來捕獲我的演員中拋出的異常。 通過代碼進行調試時,我得到了拋出的異常,但在我的測試中我從未收到異常。

應用:

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 方法中的 async/await 運算符中:

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

當執行上下文到達等待操作時,它只是在線程池(簡化)處啟動任務並返回給調用者。 即當

fooActor.Receive(true);

完成后,使用StartAsync(x)的實際任務可能尚未開始。 因此,當拋出實際異常時,您的測試已經完成,沒有任何異常。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM