2

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

  • 我有一个actor响应名为PlaceOrder
  • 我想publishes在收到另一条消息时验证这个演员PlaceOrder,在这种情况下OrderPlaced

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

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

  • ActorOfAsTestActorRef<T>
  • ActorOf<T>
  • Sys.ActorOf(...)

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

例如,这些是我有问题的 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调用的消息。我不需要在测试中注释掉这些位吗?FooOrderPlaced

可以这样做还是我完全错了?

在此先感谢,DS。

4

1 回答 1

1

PlaceOrderActor没有对 的引用FooActor,它响应的Sender是 Testkit 演员。

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

请注意,如果您将OrderPlaced消息发送到FooActor,并且不将任何消息返回给 的发件人PlaceOrderActor,则在您的测试方法中不会有明显的影响,因此您FooActor需要直接回复原始发件人,或者回到PlaceOrderActor哪个又可以回复原来的发件人。

于 2016-03-31T12:31:29.710 回答