1

2つのWCFサービスを開いているWindowsサービスがあります。OnStart()の単体テストを行い、service1.Open()とservice2.Open()が呼び出されていることを表明したいと思います。OnStart()は次のようになります。

protected override void OnStart(string[] args)
{
    // host WCF services            
    _service1.Open();           
    _service2.Open();
}

私はコンストラクターのオーバーロードにサービスを注入しています:

public WinService(ServiceHostBase service1, 
                                  ServiceHostBase service2)
{
    _service1 = service1;
    _service2 = service2;
    InitializeComponent();
}

私はRhinoMocksを使用して、次のようなServiceHostBaseのスタブを生成しています。

[TestMethod()]
public void WinServiceOnStartCallsDependenciesAsExpected()
{
    ServiceHostBase service1 = MockRepository.GenerateStub<ServiceHostBase>();
    ServiceHostBase service2 = MockRepository.GenerateStub<ServiceHostBase>();
    WinService target = new WinService(service1, service2);
    WinService_Accessor privateTarget = new WinService_Accessor(new PrivateObject(target));     
    privateTarget.OnStart(null);

テストでOnStart()を呼び出すと、service1.Open()を呼び出すときにnull参照例外が発生します。その時点でservice1がモックオブジェクトであり、nullをスローしているのはOpen()であることを確認しました。Open()が実際にはSystem.ServiceModel.Channels.CommunicationObjectのメソッドであることを知っており、それもスタブまたはモッキングを試しましたが、それでもオブジェクト参照エラーが発生します。これは仮想メソッドではないため、モックバージョンによってオーバーライドされていないだけだと思いますが、Expectationを設定しようとするとreportservice.Stub(r => r.Open())、実際のCommunicationObjectを実行しているかのように、デフォルトのタイムアウトがないという別の例外が発生します。 null参照をスローするRhinoMockyの代わりにOpen()メソッド。

つまり、ユニットテストでServiceHostでOpen()が呼び出されていることを確認する方法についてのヘルプを探しています。=]

4

1 に答える 1

1

ServiceHostBase.OpenCommunicationObject.Openボンネットの下で呼び出します。これは、その実装の一部として、オブジェクトの状態の検証、他のオブジェクトの作成、メソッド、プロパティの呼び出しなど、さまざまなことを行います。そして、それは仮想ではないので(あなたの仮定は正しかった)、Rhinoは基本クラスの実装を呼び出します。

それを機能させるには、おそらく多くのCommunicationObject依存関係をモックしてスタブする必要がありますが、それでも成功するかどうかは定かではありません(一部のタイプ/メソッドは、Rhinoでモックできない、静的、封印、またはその他の非モックである可能性があります) -バーチャル)。これが、次のいずれかを行う必要がある理由です。

  1. この種のテストは統合テストに任せてください。その後.Open、エンドユーザー環境でテストします
  2. ラッパーを導入し、ServiceHostBaseインターフェースによる依存関係として渡します。これには余分な作業(新しいインターフェイスと単純なラッパークラス)が含まれますが、必要なことを正確に実行できます

ラッパーを追加すると、問題がさらに委任されるだけであることに注意してください(ラッパークラスのOpenメソッドに委任されます。このメソッドは基本的に呼び出しServiceHostBase.Openます。これも単体テストする必要がありますか?)。一方、統合テストでは、単体テストほど速く問題を検出できない場合があります(実行頻度が低いと仮定します)。あなたがどれほど批判的であると考えるかに応じて、OnOpenあなたがどちらの方法を選んだかは多かれ少なかれ判断の呼びかけです。

于 2012-09-03T14:26:41.803 に答える