2016-03-30 19 views
2

私はまっすぐ前方統合テストをしたいというかなり単純なシナリオを持っています。高レベルの概要、次のとおりです。Akkaネット統合テスト

  • 私はこのケースで私はPlaceOrderを受信すると、この俳優publishesに別のメッセージを確認したいPlaceOrder
  • と呼ばれるメッセージに応答actorOrderPlaced

持っています問題は、統合テストでは、メッセージがExpectMsg<OrderPlaced>で公開されていると主張できます。しかし、私はまた、そのメッセージを扱う俳優を呼び出すことを期待していましたか?

おそらくTestKitの私の理解は、ここで間違っていますが、それを継承したときにあなたが得る:

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

私の印象は、ActorOf<T>Sys.ActorOf(...)なりました実際の俳優システムのように振る舞いますが、厳密な単体テストには理想的であり、俳優が送るメッセージを飲み込むことができます。私のテストはこのようになります

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 => 
      { 
      }); 
    } 
} 

:たとえば、これらは、問題の私の2人の役者

です。私は、この統合テストを自分自身を編成する必要が奇妙なこと、つまり私はOrderPlacedFooにメッセージを送信する明示的に公表されていることを確認してください。

[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。

答えて

1

PlaceOrderActorにはFooActorへの参照がありません。Senderに対応しています。これはTestkitアクタです。

FooActorOrderPlacedメッセージを受信させたい場合は、PlaceOrderActor.Handle()メソッドでメッセージを伝える必要があります。おそらく、PlaceOrderActorの子としてFooActorを作成する必要があります。そうでない場合は、システム内の他の場所(この場合はシステムにはFooActorが実行されていません)への参照を解決する必要があります。実際の(つまり、非テストの)システムでは、これはどのように機能しますか、これはこれまでのテストコードとしてのみ存在しますか?

あなたはFooActorOrderPlacedメッセージを送信する場合があることに注意してください、そして、あなたの試験方法の中から観察可能な効果は存在しません、バックPlaceOrderActorの送信者へのメッセージを教えていないので、あなたのFooActorが応答する必要があります。元の送信者に直接、または元の送信者に応答できるPlaceOrderActorに戻ることができます。

+0

私はこれについてakka net gitter roomにいたので、foo actorが動作していないように見えて、メッセージが飲み込まれているようです。私は自分のセットアップで、ActorOf Fooを追加するだけで動作すると信じています。あなたは正しいです。私はテストの観点からこれを試しただけです。私はコンソールアプリケーションでこれと非常によく似た何かを実行しています。 –

+0

私は思ったようにポストしていますので、単に 'Server'へのメッセージの送信者として機能する' Client'を作成しました。これは正常に動作するようです。すなわち、 'PlaceOrderActor'によって処理される' PlaceOrderMessage'を送信します。次に、 'Context.ActorOf(Props.Create ())を使います。(新しいOrderPlaced(message.CustomerId、message.OrderItems)))'を教えてください。しかし、TestKitを使用するとき、このメッセージは飲み込まれますか? –

+0

あなたが正しいとお詫び申し上げます。子供の俳優を作成し、治療を働いた。私が直面していた問題は、(私の知る限り) 'Sys.ActorOf()'とは別のスレッドで実行される 'ActorOfAsTestActorRef'を使用していて、' ExpectMsg <> 'のアサートが失敗していたことが起こっていました。作業用のソリューションを表示するためにポストを更新してください。 –