2014-03-02 36 views
1

我有下面的代碼我試圖寫一個單元測試:我該如何模擬這個.NET代碼?

// Grab all of the content. 
var rawContent = new StringBuilder(); 
foreach (var fileInfo in response.Files) 
{ 
    using (var stream = fileInfo.VirtualFile.Open()) 
    { 
     using (var streamReader = new StreamReader(stream)) 
     { 
      rawContent.Append(streamReader.ReadToEnd()); 
     } 
    } 
} 

現在,我已經嘲笑流實例Open()回報。這很容易。流對象也是MemoryStream,順便說一句。

但我不知道如何設置ReadToEnd() ..返回一些我有的字符串內容。這是因爲StreamReader實例對此方法是私有的。

我想提供一個可以設置的屬性。

例如。

public string AStreamReader { get; set; } 

然後做這個..

// Grab all of the content. 
var rawContent = new StringBuilder(); 
foreach (var fileInfo in response.Files) 
{ 
    using (var stream = fileInfo.VirtualFile.Open()) 
    { 
     using (var streamReader = AStreamReader ?? new StreamReader(stream)) 
     { 
      rawContent.Append(streamReader.ReadToEnd()); 
     } 
    } 
} 

,然後剛好路過一個模擬StreamReader通過AStreamReader財產。

但我真的不想這樣做。我覺得我正在泄漏一些內部邏輯,不一定......只有嘲笑!一個真正的用戶永遠不會設置..所以這感覺像一個非常骯髒的事情。

請問有人能提供一些建議嗎?

+1

難道你不能把你想要返回的數據放在你嘲笑的內存流中嗎? –

+0

@JohnKoerner正好。 'StreamReader.ReadToEnd'調用基礎流上的'.Read'。如果你能嘲笑這個流,請模擬'Read'。 – dcastro

回答

4

也許我錯過了一些東西,但如果你能嘲笑輸入Stream,爲什麼你需要嘲笑StreamReader

以下不適合你嗎?

private string ReadFromResponseFiles(Stream[] inputs) 
    { 
     var rawContent = new StringBuilder(); 
     foreach (var stream in inputs) 
     { 
      using (stream) 
      { 
       using (var streamReader = new StreamReader(stream)) 
       { 
        rawContent.Append(streamReader.ReadToEnd()); 
       } 
      } 
     } 

     return rawContent.ToString(); 
    } 

    [Test] 
    public void Can_read_files() 
    { 
     var file1 = new MemoryStream(Encoding.UTF8.GetBytes("Foo")); 
     var file2 = new MemoryStream(Encoding.UTF8.GetBytes("Bar")); 

     var result = ReadFromResponseFiles(new[] { file1, file2 }); 
     Assert.AreEqual("FooBar", result); 

     file1.Dispose(); 
     file2.Dispose(); 
    } 

} 
+0

太簡單了!我怎麼沒有看到:( –

0

將修飾符設置爲受保護的,並對其進行子類化。這就是我們如何處理大多數測試,在這種情況下。

+0

我不是主張這種方法,但將它標記爲'internal'並使用'InternalsVisibleToAttribute'給你的測試項目內部訪問會更好。 – Lukazoid

+0

這是一個更正確的方法來做到這一點,但如果你有很多組件,會更麻煩。 – JonPall