Акка Net Интеграционный Тест

У меня довольно простой сценарий, где я хочу провести прямой интеграционный тест. Обзор высокого уровня, это:

  • у меня есть 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, Мне не нужно комментировать биты в тесте?

Можно ли это сделать или я поступаю по этому поводу совершенно неправильно?

Заранее спасибо, ДС.

1 ответ

Решение

Ваш PlaceOrderActor не имеет ссылки на FooActor, это отвечает на Sender, который является актером Testkit.

Если вы хотите FooActor получить OrderPlaced сообщение, вам нужно будет сказать ему сообщение в вашем PlaceOrderActor.Handle() метод. Вы, вероятно, должны будете создать FooActor как дитя PlaceOrderActorили иным образом разрешите ссылку на него, если он находится в другом месте вашей системы (в этом случае нет FooActor работает в системе вообще). Как это работает в вашей реальной (то есть не тестовой) системе, или пока она существует только как тестовый код?

Имейте в виду, что если вы отправите OrderPlaced сообщение для FooActorи не сообщать никакое сообщение отправителю PlaceOrderActor, не будет никакого видимого эффекта в рамках вашего метода испытаний, поэтому ваш FooActor необходимо будет ответить либо непосредственно отправителю, либо обратно PlaceOrderActor который в свою очередь может ответить оригинальному отправителю.

Другие вопросы по тегам