2012-01-18 10 views
2

私はDotNetOpenAuth CTPライブラリを使用してoauthプロバイダを実装しています。そこで私はmvc3アプリケーションを作成しました。このアプリケーションには、サードパーティのアプリケーションを認証する目的で3つのメソッドを持つOAuthコントローラがあります。コントローラには、ライブラリが特定のタスクを完了するために必要なすべてのロジックをカプセル化するIOAuthServiceがありますが、サービスメソッドはコンストラクタが保護されたDotNetOpenOAuthオブジェクトを返します。ユニットテストdotnetopenauth ctp

私は自分のOAuthController内のメソッドの動作をテストしたいと思います。私はサービスメソッドをモックしようとしていますが、これを行うことはできませんでした。私はmoqライブラリにどのようなオブジェクトの型を返してもらいたいと思います。これらのオブジェクトのコンストラクタにアクセスすることができないので、私のコントローラメソッドでテストを実行することができません。

コントローラ:

public class OAuthController : Controller 
{ 
    private readonly IOAuthService _oAuthService; 

    public OAuthController(IOAuthService oAuthService) 
    { 
     _oAuthService = oAuthService; 
    } 

    [Authorize, AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)] 
    public ActionResult Authorize() 
    { 
     ClientApplication requestingClient; 
     var request = _oAuthService.ReadAuthorizationRequest(); 
     if (request == null) 
     { 
      throw new HttpException((int)HttpStatusCode.BadRequest, "Missing authorization request."); 
     } 

     var response = _oAuthService.RequestClientAuthorization(GetIdentity().Name, out requestingClient, request); 
     if (response != null) 
     { 
      return response.AsActionResult(); 
     } 

     var model = new AuthorizeClientApplicationViewModel 
     { 
      ClientApplication = requestingClient.Name, 
      Scope = request.Scope, 
      AuthorizationRequest = request, 
     }; 

     return View(model); 
    } 

    public virtual IIdentity GetIdentity() 
    { 
     return User.Identity; 
    } 
} 

私は、サードパーティ製のアプリは何の権限を持っていない時はいつでも、ビューは、アプリを承認する彼の許可を求めるユーザーにポップアップ表示されますことをテストします。 FOTこの私はモックする必要があります:

  • _oAuthService.RequestClientAuthorization

私の試験方法の設定は、次にようになります。

var oAuthService = new Mock<IOAuthService>(); 
oAuthService.Setup(a => a.RequestClientAuthorization(userName, out client, pendingRequest)).Returns(new OutgoingWebResponse()); // DotNetOpenAuth doesn't allow me to do the **new OutgoingWebResponse** 

PD:私は唯一の1を書いたこの質問のためにコントローラーのメソッドは3つあり、シナリオも同じです。

答えて

1

一つの可能​​性はラッパーを書くことである(同じようにASP.NET MVCは、すべてのHTTPコンテキスト固有のものを抽象化)今

public class OutgoingWebResponseWrapper: OutgoingWebResponseWrapperBase 
{ 
    private readonly OutgoingWebResponse _response; 
    public OutgoingWebResponseWrapper(OutgoingWebResponse response) 
    { 
     _response = response; 
    } 

    public override ActionResult AsActionResult() 
    { 
     return _response.AsActionResult(); 
    } 
} 

IOAuthService.RequestClientAuthorizationメソッドを変更してOutgoingWebResponseの代わりにOutgoingWebResponseWrapperBaseを返します。

ちょうどそのような:

public interface IOAuthService 
{ 
    ... 
    OutgoingWebResponseWrapperBase RequestClientAuthorization(...); 
} 

明らかにあなたのコントローラのコードは全く同じままになります。今では抽象クラスなので、ユニットテストでRequestClientAuthorizationの戻り値の型をモックできます。AsActionResult抽象メソッド呼び出しを模擬して、期待される模擬インスタンスを返すこともできます。そして、あなたがテストしているコントローラアクションがこの期待されるアクション結果を返したことをユニットテストでアサートします。

+0

それは私がそれを試してみることができます! – Daniel

1

コンストラクタが保護されている場合は、派生型からアクセスできます。 OutgoingWebResponseのモックを作成するために単にMoqを使用できますか(これは内部的にMoqをそれから派生させ、私が思った保護されたコンストラクタを呼び出すことができます)、あなたのモックメソッドの実装からそれを返しますか?このような

何か:

System.Net.HttpWebResponse mockResponse; // get this from somewhere 
new Moq.Mock<DotNetOpenAuth.Messaging.OutgoingWebResponse>(mockResponse, 5); 

これは、あなたがOutgoingWebResponseをモックアップさせてください。次の問題は、yoru HttpWebResponseインスタンスをどこから取得するのかということです。これも保護されたコンストラクタしかないためです。あなたはチェーンを続行し、OutgoingWebResponseと同じものをモックアップし、あなたがどれくらい遠くにいるかを見ることができます。

public abstract class OutgoingWebResponseWrapperBase 
{ 
    protected OutgoingWebResponseWrapperBase() { } 

    public abstract ActionResult AsActionResult(); 
} 

をして、ナイーブな実装があります:

+0

この理論を実装する方法の例を示す参考資料はありますか? – IamStalker

+0

いいえ、私はすでにそれを試みましたが、システムは例外をスローして、親コンストラクタに明示的に定義する必要があることを伝えます。 – Daniel

+0

例を追加しました。 1人がHttpWebResponseを持っているならば、それを行うことができます。 –

関連する問題