Akka Net Integration Test

时间:2016-03-30 16:29:43

标签: c# akka.net testkit

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

  • 我有一个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,这应该在处理Foo时调用OrderPlaced。我不需要在测试中注释掉这些位吗?

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

提前致谢,DS。

1 个答案:

答案 0 :(得分:1)

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

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

请注意,如果您向OrderPlaced发送FooActor消息,并且不向PlaceOrderActor的发件人发回任何消息,则内部将不会有任何可观察到的效果您的测试方法,因此您的FooActor需要直接回复原始发件人,或返回PlaceOrderActor,而-(void) someFunction { __block NSString *nameIWillUseInBlock = @"Some name"; //Here ill use the __block [self functionWithCallback:^(NSString *string) { NSString *stringWithString = [NSString stringWithFormat:@"%@%@", nameIWillUseInBlock, @"with bla"]; //Here Ill do somthing with this string }]; } 可以回复原始发件人。