2012-03-06 17 views
8

我々は確かに、きめ細かなWebサービス(WCFのREST)が多数必要となるサービス指向フレームワーク(SOA)を構築しようとしています。私たちは、クライアント側とサーバー側のコードベースの単体テストを徹底的に練ってきましたが、単体テストWebサービスの経験はあまりありません。私たちは実際にテストを書くべき場所や、私たちのサービスを単体テストするときにどのようなアプローチをとるべきかについてのガイダンスを探しています。ユニットテストWebサービスの推奨パターン

httpリクエストを行い、レスポンスが何であるべきであると主張するテストを書くべきでしょうか?実際のリクエストをテストすることを心配するのではなく、サービスメソッド自体の内部ロジックをテストするだけに焦点を当てるべきでしょうか?それとも両方を行うべきですか?私たちは何をテストすべきか他の推奨事項はありますか?

我々は本当にいくつかの説明とガイダンスを探しており、私たちが得ることのできるアドバイスを本当に感謝しています。

答えて

11

私は、次のシナリオでは、通常のユニットテストの上に便利なテストのWebサービス、特にWCFクライアントとサーバを発見した:あなたがブラックボックスにしたい

  1. 受け入れテストは、あなたの全サービスをテストし、物事を突きます四肢で
  2. 特定のWCFワイヤアップ、拡張、動作などのテスト
  3. インターフェイスとデータメンバーが正しく設定されているかどうかのテスト。

ほとんどの場合、私は基本的なhttpを使って非常に基本的な設定を使用し、コード内のすべてを配線しようとします。私が統合テストまたは受入れテストでない限り、私はサーバーに対してクライアントをテストせず、代わりに別のものをテストできるように、そのうちの1つを模擬します。以下は、私がWCFクライアントおよびサービスをテストする方法の例です:私はあなたがして城動的プロキシを使用するものを使用してWCFサービスをモックとしたい場合は、あなたがすることを言及するのを忘れていた

public static ServiceHost CreateServiceHost<TServiceToHost>(TServiceToHost serviceToHost, Uri baseAddress, string endpointAddress) 
{ 
    var serviceHost = new ServiceHost(serviceToHost, new[] { baseAddress }); 

    serviceHost.Description.Behaviors.Find<ServiceDebugBehavior>().IncludeExceptionDetailInFaults = true; 
    serviceHost.Description.Behaviors.Find<ServiceBehaviorAttribute>().InstanceContextMode = InstanceContextMode.Single; 

    serviceHost.AddServiceEndpoint(typeof(TServiceToHost), new BasicHttpBinding(), endpointAddress); 

    return serviceHost; 
} 

//Testing Service 

[TestFixture] 
class TestService 
{ 
    private ServiceHost myServiceUnderTestHost; 
    private ChannelFactory<IMyServiceUnderTest> myServiceUnderTestProxyFactory; 
    [SetUp] 
    public void SetUp() 
    { 
     IMyServiceUnderTest myServiceUnderTest = new MyServiceUnderTest(); 
     myServiceUnderTestHost = CreateServiceHost<IMyServiceUnderTest>(myServiceUnderTest, new Uri("http://localhost:12345"), "ServiceEndPoint"); 
     myServiceUnderTestHost.Open(); 

     myServiceUnderTestProxyFactory = new ChannelFactory<IMyServiceUnderTest>(new BasicHttpBinding(), new EndpointAddress("http://localhost:12345/ServiceEndPoint")); 
    } 

    [TearDown] 
    public void TearDown() 
    { 
     myServiceUnderTestProxyFactory.Close(); 
     myServiceUnderTestHost.Close(); 
    } 

    [Test] 
    public void SomeTest() 
    { 
     IMyServiceUnderTest serviceProxy = myServiceUnderTestProxyFactory.CreateChannel(); 

     serviceProxy.SomeMethodCall(); 
    } 
} 

//Testing Client 

[TestFixture] 
class TestService 
{ 
    private ServiceHost myMockedServiceUnderTestHost; 
    private IMyServiceUnderTest myMockedServiceUnderTest; 

    [SetUp] 
    public void SetUp() 
    { 
     myMockedServiceUnderTest = Substitute.For<IMyServiceUnderTest>(); //Using nsubstitute 
     myServiceUnderTestHost = CreateServiceHost<IMyServiceUnderTest>(myMockedServiceUnderTest, new Uri("http://localhost:12345"), "ServiceEndPoint"); 
     myServiceUnderTestHost.Open(); 
    } 

    [TearDown] 
    public void TearDown() 
    { 
     myServiceUnderTestHost.Close(); 
    } 

    [Test] 
    public void SomeTest() 
    { 
     //Create client and invoke methods that will call service 
     //Will need some way of configuring the binding 
     var client = new myClientUnderTest(); 

     client.DoWork(); 

     //Assert that method was called on the server 
     myMockedServiceUnderTest.Recieved().SomeMethodCall(); 
    } 
} 

NOTE

ServiceContractAttributeがモックにコピーされないようにする必要があります。私はこれにblog postを持っていますが、基本的にはモックを作成する前にレプリケーションを防ぐために属性を1つとして登録します。

Castle.DynamicProxy.Generators.AttributesToAvoidReplicating 
    .Add<ServiceContractAttribute>(); 
3

基本的に私はあなたが2つの部分のテスト戦略を持つ必要があると思います。

最初の部分は真の単体テストになります。これは、Web要求とは完全に独立してクラスをテストすることになります。単体テストの主な定義は余分な環境や設定を必要とせずに実行するものですテスト自体のものよりも。

ユニットテストプロジェクトを作成すると、残りのクラスをテストするのと同じように、ロジックが正しいことを確認するためにWCFサービスのコードクラスをインスタンス化します。

第2の部分は、アプリケーションをエンドツーエンドでテストする統合テストのセットです。もちろん、ここではエンチラダ、ウェブサーバー、データベースなどが必要です。

この方法で、ロジックが正確であり、アプリケーションが動作することがわかります。

関連する問題