2016-03-30 6 views
2

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

  • У меня есть 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 это должно invoke Foo как он обрабатывает OrderPlaced. Мне не нужно было бы, чтобы бит был прокомментирован в тесте?

Можно ли это сделать, или я об этом совершенно не так?

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

ответ

1

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

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

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

+0

Я был на обсервативной комнате akka net об этом, и кажется, что у меня нет действующего игрока foo, поэтому сообщение проглочено. Я верю в свою настройку, мне просто нужно добавить ActorOf Foo, и он должен работать. Вы правы, я только пробовал это с точки зрения теста. У меня есть что-то очень похожее на это в консольном приложении. –

+0

Вы меня задумали, поэтому я создал «Клиент», который просто служит отправителем сообщений на «Сервер». Кажется, это работает нормально, т. Е. Я отправляю 'PlaceOrderMessage', который обрабатывается' PlaceOrderActor'. Затем я использую 'Context.ActorOf (Props.Create ()). Сообщите (новый OrderPlaced (message.CustomerId, message.OrderItems));'. Однако при использовании TestKit это сообщение проглатывается? –

+0

Извините, что вы правы. Созданный ребенок-актер работал с удовольствием. Проблема, с которой я просто сталкивалась, заключалась в том, что я использовал 'ActorOfAsTestActorRef', который работает по отдельному потоку в' Sys.ActorOf() '(насколько мне известно), и поэтому утверждение' ExpectMsg <> 'не срабатывало. Обновление сообщения, чтобы показать рабочее решение. –

Смежные вопросы