2009-07-25 16 views
12

私はいくつかの追加機能を追加するHttpApplicationから派生したクラスを持っています。私はこれらの機能をユニットテストする必要があります。つまり、HttpApplicationの新しいインスタンスを作成し、リクエストを偽装し、レスポンスオブジェクトを取得できる必要があります。HttpApplicationのユニットテスト

HttpApplicationオブジェクトのユニットテストについては、どのように正確にテストしますか?私は現時点でMoqを使用していますが、必要なモックオブジェクトを設定する方法はわかりません。

答えて

10

HttpApplicationが非常に簡単に嘲笑に向いていないので、残念ながら、これは特に簡単ではありません。模擬するインターフェースはなく、ほとんどのメソッドは仮想としてマークされていません。

私は最近、HttpRequestとHttpWebResponseで同様の問題が発生しました。これは私が私自身のラッパーに対して嘲笑しましょうなど

public class HttpWebRequestWrapper : IHttpWebRequestWrapper 
    { 
     private HttpWebRequest httpWebRequest; 

     public HttpWebRequestWrapper(Uri url) 
     { 
      this.httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url); 
     } 

     public Stream GetRequestStream() 
     { 
      return this.httpWebRequest.GetRequestStream(); 
     } 

     public IHttpWebResponseWrapper GetResponse() 
     { 
      return new HttpWebResponseWrapper(this.httpWebRequest.GetResponse()); 
     } 

     public Int64 ContentLength 
     { 
      get { return this.httpWebRequest.ContentLength; } 
      set { this.httpWebRequest.ContentLength = value; } 
     } 

     public string Method 
     { 
      get { return this.httpWebRequest.Method; } 
      set { this.httpWebRequest.Method = value; } 
     } 

     public string ContentType 
     { 
      get { return this.httpWebRequest.ContentType; } 
      set { this.httpWebRequest.ContentType = value; } 
     } 
} 

など:最後に、私が行った解決策は、私が使用していた方法のためのストレート「パススルー」ラッパーを作成することでしたインタフェース。必ずしも世界でもっともエレガントなものではありませんが、フレームワークのあまり「あざける」部分を模倣する非常に便利な方法です。あなたがオフに急ぐといえ、これを行う前に

、それはあなたが持っているものの見直し、あなたがクラスをラップすることを避けるためでしょう、あなたのテストへのより良いアプローチがあれば見る価値があります。

HttpWebRequest、HttpApplicationらの場合、IMHOはしばしばありません。

あなたは、その後部品番号で、このようなものを行う(上記の私のHttpWebRequestの例を使用して)モックでこのラッパーを設定するには:

var mockWebRequest = new Mock<IHttpWebRequestWrapper>(); 
mockWebRequest.SetupSet<string>(c => c.Method = "POST").Verifiable(); 
mockWebRequest.SetupSet<string>(c => c.ContentType = "application/x-www-form-urlencoded").Verifiable(); 
mockWebRequest.SetupSet<int>(c => c.ContentLength = 0).Verifiable(); 
+0

感謝を!私は少し物をリファクタしたので、余分な機能のほとんどは、HttpApplicationに頼るのではなく、嘲笑されたHttpContextBaseだけで作成できる外部クラスになりました。 –

2

IMHOは、HttpApplicationを拡張して機能を追加するのが最善の方法ではありません。プライベート/内部/密閉クラスのため、HttpContextをモックするのはとても難しいです。単体テストが成功したとしても、実際にテストしていることを理解できなくなるコードを嘲笑してしまいます。

追加している機能の詳細を教えてください。おそらく、この機能をアプリケーションに追加するより良い方法があります。

2

私はマイクロソフトほくろを使用して、非常に素敵なアプローチを説明し、以前の次のブログを見つけました。

http://maraboustork.co.uk/index.php/2011/03/mocking-httpwebresponse-with-moles/

要するにソリューションは、次のことを示唆している:情報のため

[TestMethod] 
    [HostType("Moles")] 
    [Description("Tests that the default scraper returns the correct result")] 
    public void Scrape_KnownUrl_ReturnsExpectedValue() 
    { 
     var mockedWebResponse = new MHttpWebResponse(); 

     MHttpWebRequest.AllInstances.GetResponse = (x) => 
     { 
      return mockedWebResponse; 
     }; 

     mockedWebResponse.StatusCodeGet =() => { return HttpStatusCode.OK; }; 
     mockedWebResponse.ResponseUriGet =() => { return new Uri("http://www.google.co.uk/someRedirect.aspx"); }; 
     mockedWebResponse.ContentTypeGet =() => { return "testHttpResponse"; }; 

     var mockedResponse = "<html> \r\n" + 
          " <head></head> \r\n" + 
          " <body> \r\n" + 
          "  <h1>Hello World</h1> \r\n" + 
          " </body> \r\n" + 
          "</html>"; 

     var s = new MemoryStream(); 
     var sw = new StreamWriter(s); 

      sw.Write(mockedResponse); 
      sw.Flush(); 

      s.Seek(0, SeekOrigin.Begin); 

     mockedWebResponse.GetResponseStream =() => s; 

     var scraper = new DefaultScraper(); 
     var retVal = scraper.Scrape("http://www.google.co.uk"); 

     Assert.AreEqual(mockedResponse, retVal.Content, "Should have returned the test html response"); 
     Assert.AreEqual("http://www.google.co.uk/someRedirect.aspx", retVal.FinalUrl, "The finalUrl does not correctly represent the redirection that took place."); 
    } 
関連する問題