2011-02-17 52 views
7

正如Richard Willis在http://blog.salamandersoft.co.uk/index.php/2009/10/how-to-mock-httpwebrequest-when-unit-testing/中建議的那樣,我試圖調用一個Web請求來喚起行爲。爲此(我問我是否在這裏搞點東西)我實現了IWebRequestCreate並擴展了WebRequest和WebResponse。 (更多鏈接代碼的詳細信息)使用.Net WebRequest工廠

但現在在我的代碼我有一個測試寄存器(WebRequest.RegisterPrefix)的前綴:

[Test] 
public void Test() { 
    var some = File.ReadAllBytes(@"TestData\WebService\admrond_13jan2011_14jan2011.xml"); 
    WebRequest.RegisterPrefix("mockPrefix", new WebRequestCreateMock()); 
    WebRequestFake request = WebRequestCreateMock.CreateRequestFake(some); 

    _remoteRepository.PopulateWithMeterData(_meter); 
    ... (error in line before) 

然後,我得到這個錯誤:Invalid URI: The hostname could not be parsed.

但是,爲什麼?在我PopulateWithMeterData(Meter meter)我有這樣的電話:

 WebRequest request = WebRequest.Create(urlListMeteringData); 
    WebResponse ws = request.GetResponse(); 

一些建議嗎?在我的課程實施過程中有趣嗎?


編輯:爲@Matthew問:

public class WebRequestCreateMock : IWebRequestCreate { 

    static WebRequest _nextRequest; 
    static readonly object LockObject = new object(); 

    static public WebRequest NextRequest { 
     get { return _nextRequest; } 
     set { 
      lock (LockObject) { 
       _nextRequest = value; 
      } 
     } 
    } 

    public WebRequest Create(Uri uri) { 
     return _nextRequest; 
    } 

    public static WebRequestFake CreateRequestFake(byte[] xmlStream) { 
     WebRequestFake webRequestFake = new WebRequestFake(xmlStream); 
     NextRequest = webRequestFake; 
     return webRequestFake; 
    } 

} 

public class WebRequestFake : WebRequest { 
    MemoryStream requestStream = new MemoryStream(); 
    MemoryStream responseStream; 

    public override string Method { get; set; } 
    public override string ContentType { get; set; } 
    public override long ContentLength { get; set; } 

    public WebRequestFake(byte[] response) { 
     responseStream = new MemoryStream(response); 
    } 

    public override Stream GetRequestStream() { 
     return requestStream; 
    } 

    public override WebResponse GetResponse() { 
     return new WebReponseFake(responseStream); 
    } 
} 

public class WebReponseFake : WebResponse { 

    private readonly Stream _responseStream; 

    public WebReponseFake(Stream responseStream) { 
     _responseStream = responseStream; 
    } 

    public override Stream GetResponseStream() { 
     return _responseStream; 
    } 
} 

和URL是一樣的東西:mockPrefix://NoMatterUrl

+0

我會更充實你的代碼,並舉例說明你用來創建請求的URL。 – 2011-02-17 19:51:26

+0

@Custodio我想使用rtmp鏈接將它傳遞給HTTPHanlder以獲取vlc插件視頻目標源。你能幫助我如何使用你的代碼在閱讀直播流到vlc插件播放器[我的問題在這裏](http://stackoverflow.com/questions/21862260/http-handler-returns-target-source-for-vlc-plugin -player) – ZahidKakar 2014-02-21 07:14:18

回答

3

由於錯誤是「無效的URI:無法解析主機名。」你可能搞砸了你的Uri「mockPrefix:// NoMatterUrl」

我曾經遇到這個問題,因爲我忘了在域uri和請求參數之間添加「/」。

你能準確地發佈你的「NoMatterUri」嗎?

1

您需要使用一個冒號( ':')註冊您的前綴;如:

WebRequest.RegisterPrefix("mockPrefix:", new WebRequestCreateMock()); 
+0

好的!我也試過冒號。不工作:( – Custodio 2011-02-17 20:39:13

0

我發現有必要在前綴中包含尾隨「/」。例如,「test://localhost/」:

[TestClass] 
public class WebRequestTests 
{ 
    [TestMethod] 
    public void TestWebRequestCreate() 
    { 
     const string uriString = "test://localhost/foo/bar.baz?a=b&c=d"; 
     var webRequest = new MockWebRequestCreateAssertUrl(uriString); 
     Assert.IsTrue(WebRequest.RegisterPrefix("test://localhost/", webRequest), 
         "Failed to register prefix"); 
     Assert.IsNotNull(WebRequest.Create(uriString)); 
    } 

    public class MockWebRequestCreateAssertUrl : IWebRequestCreate 
    { 
     private readonly Uri _expectedUri; 

     public MockWebRequestCreateAssertUrl(string uriString) 
     { 
      _expectedUri = new Uri(uriString); 
     } 

     public WebRequest Create(Uri uri) 
     { 
      Assert.AreEqual(_expectedUri, uri, "uri parameter is wrong"); 
      return new MockWebRequestAssertUrl(); 
     } 
    } 

    public class MockWebRequestAssertUrl : WebRequest {} 
}