Akka 网络集成测试

Akka Net Integration Test

我有一个相当简单的场景,我想在其中进行直接的集成测试。高级概述是:

问题是,对于集成测试,我可以断言该消息已通过 ExpectMsg<OrderPlaced> 发布。但是,我也期待它调用任何处理该消息的演员?

也许我对 TestKit 的理解在这里是不正确的,但是从它继承时你会得到:

我的印象是,ActorOf<T>Sys.ActorOf(...) 会表现得像一个真正的 actor 系统,而 ActorOfAsTestActorRef<T> 将是严格单元测试的理想选择,并且吞噬 actor 可能反过来的任何消息发送。

例如,这些是我的 2 个演员:

public class PlaceOrderActor : ReceiveActor
{
    public PlaceOrderActor()
    {
        this.Receive<PlaceOrderMessage>(
            message =>
            {
                this.Handle(message);
            });
    }

    private void Handle(PlaceOrderMessage message)
    {
        Context.ActorOf(Props.Create<Foo>()).Tell(new OrderPlaced(message.CustomerId, message.OrderItems));
    }
}

public class Foo : ReceiveActor
{
    public Foo()
    {
        this.Receive<OrderPlaced>(
            m =>
            {
            });
    }
}

我的测试是这样的。奇怪的是,我必须自己安排这个集成测试,即我检查 OrderPlaced 是否已发布,然后明确地向 Foo:

发送消息
[TestFixture]
public class IntegrationTest : TestKit
{
    [Test]
    public void When_Placing_An_Order()
    {
        var message = new PlaceOrderMessage(
            "123",
            new List<OrderItem>
            {
                new OrderItem("Product ABC", 2)
            });

        this.ActorOfAsTestActorRef<PlaceOrderActor>().Tell(message);

        var orderPlaced = this.ExpectMsg<OrderPlaced>();

        //if (orderPlaced != null)
        //{
            //this.ActorOfAsTestActorRef<Foo>().Tell(orderPlaced);
        //}
    }
}

我期望的是,通过发送消息 PlaceOrder,这应该在处理 OrderPlaced 时调用 Foo。我不需要在测试中注释掉这些位吗?

这可以做到还是我的做法完全错误?

提前致谢,DS。

您的 PlaceOrderActor 没有对 FooActor 的引用,它响应 Sender,即 Testkit 参与者。

如果您希望 FooActor 接收 OrderPlaced 消息,您需要在 PlaceOrderActor.Handle() 方法中将消息告诉它。您可能需要创建 FooActor 作为 PlaceOrderActor 的子项,或者如果它在您的系统中的其他地方则解析对它的引用(在这种情况下没有 FooActor 运行 在系统中)。这在您的实际(即非测试)系统中如何工作,或者目前仅作为测试代码存在?

请注意,如果您将 OrderPlaced 消息发送给 FooActor,并且不将任何消息返回给 PlaceOrderActor 的发件人,则不会有明显的效果从您的测试方法中,因此您的 FooActor 将需要直接响应原始发件人,或者返回 PlaceOrderActor 进而可以响应原始发件人。