2012-01-20 17 views
4

C#GData YouTube APIで動作するサービスクラスを作成しました。 APIの一般的な使用方法は、YouTubeRequestオブジェクトにリクエストを送信することです。このオブジェクトは、YouTube Webサービスを呼び出し、かなりの形式のデータを含むFeedVideo、またはのインスタンスでJSON形式のレスポンスを逆シリアル化しますC#のプロパティはほとんどありません。.NETのYouTube GData APIのオブジェクトをモック

私は、このサービスクラスのユニットテストしたいです。私のコードでは、YouTubeRequestオブジェクトは外部依存関係であり、嘲笑される必要がありますが、インタフェースを実装していないため、自分自身の抽象レイヤーを追加する必要がありました。この層にはVideoPlaylistの型を返すメソッドがあり、テストデータを持つダミーのVideoインスタンスを作成するモックオブジェクトを作成するのにMoqを使用しようとしていますが、Videoクラスのプロパティの多くは読み込み専用ですが、これらのVideo,、およびオブジェクトは作成が難しく、YouTubeフレームワークの他のタイプのインスタンスを必要とすることがよくあります。

私はユニットテストに非常に新しいですが、私はそれのロブConeryさんの動画を見てきたものから、ASP.NET Webフォームのような優しいユニットテストではありませんいくつかのフレームワークは、単にそこにあります。

この場合、どうすればよいですか? YouTubeRequestオブジェクトを間違って抽象化していますか?この抽象レイヤーは非常にシンプルでなければなりませんが、マッピングレイヤーへの呼び出しを追加すると、データを自分のタイプにマッピングできます。私の型を返すインターフェイスを偽装するほうがはるかに簡単です。&プロパティを設定してダミーデータを簡単に作成することができます。 YouTubeとやりとりするコードは比較的少ないのですが、時間が経つにつれてサイズや複雑さが増し、単体テストを放棄するというアイデアは厄介です。プレゼンテーション、ビジネス、およびデータ:

+2

実際に*模擬する必要がありますか、それともあなた自身でインスタンスを作成できますか?モーキングはサービスには意味がありますが、単純な* data *クラスを使用している場合は、インスタンスを自分で作成してください。 –

+1

これをさらにラップして、抽象レイヤーを複雑にすることができます。代わりに、[impromptu-interface](http://code.google.com/p/impromptu-interface/)は、自分のクラスをあなたのインターフェースにダックタイプさせるかもしれません。私はまだそれを試していない。 – TrueWill

+0

@ JonSkeetあなたはそれを嘲笑せずにインタフェースの偽の実装を書くことを意味しますか?はい、私はそれを行うことができますが、たとえ私が偽の実装を書いていたとしても、そのプロパティを設定できないと、この偽のバージョンがビデオオブジェクトとプレイリストオブジェクトにダミーデータを返すことができますか? YouTubeRequestオブジェクトを使用するサービスクラスは、返されるVideo、Playlist、Feedオブジェクトで動作します。これは、サービスクラスをテストするために偽造したいデータです。この問題は、ダミーのVideo、Playlist、およびFeedインスタンスを簡単に構築できないことと強く関連しています。 –

答えて

0

一般的にC#でこのテスト可能なようなものを作るための最善の方法は、システム内の三つの異なるモジュールを持つことです。あなたの場合、YouTube APIはデータモジュールです。テスト容易性をより簡単にするYouTubeデータサービスを作成する方法の1つは、APIを呼び出して応答(XML/JSON/etc)をPOCO(Plain-Old C#Objects)に変換することです。これらのPOCOSはおそらくちょうどそうのようなAPIのスキーマに正確にマッピングされているパブリックプロパティを持つクラスを次のようになります。

namespace YouTube 
{ 
    public class Video 
    { 
     public string Title { get; set; } 

     public int Views { get; set; } 

     // etc 
    } 
} 

これらは、ほとんど、あるいはまったくロジックを持っており、単にAPIの安息の内部表現されている必要があります。これで、実際にテストするアプリケーションのテストデータ、つまりビジネスレイヤを簡単に作成できるようになりました。あなたはPOCOからより複雑なオブジェクトを作成することができ、簡単にテストでそれを行うことができます。

次に、あなたのプレゼンテーション層は、ビジネス層と通信し、あなたが望むなら、あなたはプレゼンテーション層をテストするために、あなたのビジネス層を模擬することができます。

+0

さて、YouTubeのC#ライブラリはYouTubeのWebサービスを呼び出し、このJSONをPCOOに翻訳してくれます。 POCO自体は非常に複雑で、JSON.NETを使用して独自のカスタムVideoオブジェクトへのマッピングを行うことはできますが、これはGoogleのC#YouTubeクライアントライブラリを自分のバージョンに置き換えることができます。私は手動でWebサービスのURLを呼び出し、JSON.NETにデータを渡します。私はそれが解決策だと思いますが、オーバーヘッドのように感じます。 –

0

もう少し前後に反転します。

YouTubeのオブジェクトがすでにそれのオフにぶら下がっこれらのフィールドを持っているかもしれませんが、そうでないと仮定します。 IFeedSourceのようなインターフェイスを実装し、GetFeedForVideo (YouTubeVideo)というメソッドを与えます。このようにして、細かいテスト容易性を得ることができます(Param<YouTubeVideo>.Is.Anything)、オブジェクトを簡単に返すことができます。

1

私は擬似ダミーVideoPlaylistオブジェクトを正常に生成しました。私のモックインプリメンテーションでそれらを戻しています。これらのタイプの特定のプロパティは読み込み専用ですが、「AtomFeed」という別のプロパティが見つかりました。これは取得プロパティ&です。結果として、VideoおよびPlaylistオブジェクトのすべての読み取り専用プロパティは、AtomFeedプロパティで指定されたオブジェクトからデータを取得します。私はYouTube .NET Client Libraryのソースコードを読んでこれを発見しました。結局のところ、私の問題は自分のYouTubeライブラリの悪用から生まれました。その結果、この回答は、YouTubeライブラリの特定の問題のみを解決するものであり、複雑で設定不可能なプロパティを返さなければならないインターフェースを嘲笑することに関連する一般的な問題ではありません。

0

パラメータのないコンストラクタ、仮想メソッド、インターフェイス、または抽象基底クラスがないため、何かを模擬することができないときはいつでも、モックを容易にするためのラッパークラスを作成できます。

Resharperでは、プライベートメンバーフィールドでAlt + Insertを押してから、「委任メンバー」オプションを選択すると、これをはるかに簡単に行うことができます。 Resharperは、すべてのパブリックメソッドとプロパティを作成し、そのプロパティ/メソッドを選択したプライベート変数に委譲することで、ラッパークラスを作成します。例えば

private readonly Feed<T> _feed; 

あなたはその後、適切なコンストラクタを作成することができますし、フィードを返却する必要がある時はいつでも今、ちょうどGDataFeedWrapperを返すので

public class GDataFeedWrapper<T> where T : Entry, new() 
{ 
    private readonly Feed<T> _feed; 

    public GDataFeedWrapper(Feed<T> feed) 
    { 
     _feed = feed; 
    } 

    public virtual AtomFeed AtomFeed 
    { 
     get { return _feed.AtomFeed; } 
    } 

    public virtual bool AutoPaging 
    { 
     get { return _feed.AutoPaging; } 
     set { _feed.AutoPaging = value; } 
    } 

    public virtual IEnumerable<T> Entries 
    { 
     get { return _feed.Entries; } 
    } 

    public virtual int Maximum 
    { 
     get { return _feed.Maximum; } 
     set { _feed.Maximum = value; } 
    } 

    public virtual int PageSize 
    { 
     get { return _feed.PageSize; } 
    } 

    public virtual int StartIndex 
    { 
     get { return _feed.StartIndex; } 
    } 

    public virtual int TotalResults 
    { 
     get { return _feed.TotalResults; } 
    } 
} 

のように仮想としてテスト可能なすべてのメソッド/プロパティをマーク。

関連する問題