2015-11-15 9 views
16

信頼できるサービス/アクタをコンストラクタを呼び出してテストすることはできません。 var testService = new SomeService();はNullReferenceExceptionをスローします。だから私は、私が展開SF信頼性の高いサービス/アクターが標準の.NETクラス、および展開S/A多分奇妙なアイデアのユニットテストではないことを理解しサービスファブリックユニットのテストと依存性注入

..展開サービスで何を行うことができます。

とにかく私はそれを試してみようとしています。

たとえば、私はサービスを実装したばかりです。テストでは、プロキシオブジェクトを作成し、項目をサービスの入力キューに追加しました。次に、入力キューの数を1にする必要があります。サービスをデプロイしたばかりで、他のクライアント/サービス/アクターが入力キューを使用していない場合に機能します。しかし、次回はこのテストは失敗しますが、それは問題です。私は他の消費者とのオペレーションをやめ、それをキューに入れてテストするよりもサービスを停止する必要があります。この目的のために、いくつかのTestModeプロパティとPropareoForTests/TestingCompletedのようないくつかのメソッドを作成し、テストの前と後にテストクライアントから呼び出すことができます。

このようにするのは悪い考えですか?おそらくユニットテストSFのためのいくつかのガイドラインはありますか?ありがとう。

UPDATE:Service Fabric Web Reference Application exampleを調査している間

私はこのTODO文字列を見つけた:

/// TODO: Temporary property-injection for an IServiceProxyWrapper until constructor injection is available. 

それはSFサービスは、それがDIのサポートだ改善されることを意味していますか?俳優はどうですか?

+3

実際にアクタでコンストラクタ依存性注入が利用可能になりました!あなたのアクタータイプを登録するときには、アクタークラスインスタンスを作成する実際のFunc <>である "ファクトリ"を登録することもできます。サービスでは、すでにこれを行うことができます。パーティクルクラスのサンプルでは、​​どのように行うのかを確認してください:https://github.com/Azure-Samples/service-fabric-dotnet-management-party-cluster/tree/master/PartyCluster/ ClusterService –

+1

私は1との依存性注入を行う際の答えを書いた:http://stackoverflow.com/questions/30384780/azure-service-fabric-actor-dependency-injection/35900027#35900027 –

+0

@VaclavTurecekあなたのリンクが壊れている – Dismissile

答えて

16

実はあなたは信頼性の高いサービスや俳優は、.NETで、他のクラスをテストしたいのと同じ方法をテストすることができます!彼らは、基盤となるプラットフォームに特定のフックを使用する点でのみ特別ですが、サービスやアクタークラスをインスタンス化してメソッドを呼び出すことができます。

は現在、信頼性の高いサービスをプラットフォームに主フックので、ユニットテストに少し楽にしている、状態マネージャは、コンストラクタでプラグ可能だインタフェースです。そして、あなたがそうのようなあなたのサービスクラスをテストすることができGAリリースのAPIを更新(2.0.135)

class MyService : StatefulService 
{ 
    public MyService (StatefulServiceContext context, IReliableStateManager stateManager) 
     :base (context, stateManager) 
    { 
    } 

    public void MyMethod() 
    { 
    // do stuff.. 
    } 
} 

EDIT:たとえば、あなたのサービスクラスは次のようになります

[TestMethod] 
public TestMyMethod() 
{ 
    MockReliableStateManager stateManager = new MockReliableStateManager(); 
    MyService target = new MyService(stateManager); 

    target.MyMethod(); 
    // validate results and all that good stuff 
} 

私たちは、依存関係の多くは、GitHubの上で利用できるテストユニットであることと、実際のサービスの完全な作業例を持っています。https://github.com/Azure-Samples/service-fabric-dotnet-management-party-cluster

この例ではIReliableStateManagerとIReliableDictionaryは同様にあなたがあなた自身のユニットテストのための出発点として使用できることを皮肉っています。

+0

ありがとう、 Vaclav!これはまさに必要なものです。アップデートを見てください。 – AsValeO

+1

RTM(Actors 2.0.135)では、 'Actor.StateManager'プロパティは読み取り専用です(' protected set'はありません)。アクタークラスの状態マネージャの依存関係をどのように注入すればよいですか? –

+0

そして、俳優のリマインダーとタイマーはどうですか? 'ReceiveReminderAsync'メソッドは自分で呼び出すことができますが、' RegisterReminderAsync'( 'ActorBase'のprotectedメソッド)に対して行われた呼び出しを確認する必要があります。 –

4

は、信頼性の高い俳優の状態マネージャをあざけるために、あなたはこのような何かを行うことができます。

private readonly IActorStateManager _stateManager; 

public MyActor(IActorStateManager stateManager = null) 
{ 
    _stateManager = stateManager ?? this.StateManager; 
} 

実は、StateManagerは、まだこの時点で初期化されていません。

private IActorStateManager _stateManager; 

// Unit tests can inject mock here. 
public MyActor(IActorStateManager stateManager = null) 
{ 
    _stateManager = stateManager; 
} 

protected override async Task OnActivateAsync() 
{ 
    if (_stateManager == null) 
    { 
     _stateManager = StateManager; 
    } 
} 

ちょうど常に代わりthis.StateManagerのコードの残りの部分で_stateManagerを使用してください:OnActivateAsyncが呼び出されたときに、私たちはそれを得ることができます。