2015-05-13 25 views
10

我有ImportProvider類,我想爲Import方法編寫單元測試。如何爲使用流作爲參數的方法編寫unitTest

但是這應該是單元測試,所以我不想從文件讀取流。 有什麼想法?

public class ImportProvider : IImportProvider 
{ 
    public bool Import(Stream stream) 
    { 
     //Do import 

     return isImported; 
    } 
} 

public interface IImportProvider 
{ 
     bool Import(Stream input); 
} 

這是單元測試:

[TestMethod] 
public void ImportProvider_Test() 
{ 
    // Arrange   
    var importRepository = new Mock<IImportRepository>(); 
    var imp = new ImportProvider(importRepository.Object); 
    //Do setup... 

    // Act 
    var test_Stream = ????????????? 
    // This working but not option: 
    //test_Stream = File.Open("C:/ExcelFile.xls", FileMode.Open, FileAccess.Read); 
    var result = imp.Import(test_Stream); 

    // Assert  
    Assert.IsTrue(result); 
} 
+0

你能改變產品代碼嗎? –

回答

22

使用MemoryStream。不知道你的函數需要什麼,但飽食一頓UTF-8字符串到它,例如:

//Act 
using (var test_Stream = new MemoryStream(Encoding.UTF8.GetBytes("whatever"))) 
{ 
    var result = imp.Import(test_Stream); 

    // Assert  
    Assert.IsTrue(result); 
} 

編輯:如果你需要一個Excel文件,你是無法從磁盤中讀取文件,您可以加入一個Excel文件作爲測試項目中的嵌入式資源?見How to embed and access resources by using Visual C#

然後,您可以讀出這樣的數據流:

//Act 
using (var test_Stream = this.GetType().Assembly.GetManifestResourceStream("excelFileResource")) 
{ 
    var result = imp.Import(test_Stream); 

    // Assert  
    Assert.IsTrue(result); 
} 
+0

我的函數期望來自excel文件的數據。 test_Stream = File.Open(「C:/ Excel file.xls」,FileMode.Open,FileAccess.Read); – Raskolnikov

+2

任何你不能加載測試文件的原因? – GazTheDestroyer

+0

我沒有編寫集成測試的權限:) – Raskolnikov

3

您可以使用一個MemoryStream爲您提供測試純粹的內存流。

0

使用像JustMock,TypeMock或Microsoft僞造品,你隔離框架將能嘲笑流。

壞消息是,據我所知,他們都支付。

+0

我認爲它歸結爲兩件事情:1)像NSubstitute這樣的模擬框架完全可以自由使用,2)可以「模擬」流而不必模擬實際的流類型,因爲a)「Stream」類型本身可以直接在任意子類中擴展,並且b)如果你所需要的只是讀或寫數據,內建的'MemoryStream'類型可以提供'Stream'語義和'byte []'緩衝區。所以,這個答案並沒有準確地表徵問題空間或潛在的解決方案。 –

+0

@JonathanGilbert:你可能認爲還有其他的選擇,你可能會認爲他們比這個更好,但我認爲隔離框架是解決這個問題的一個潛在的解決方案是不可爭議的。 –

+1

好的,是的,從技術上講,你可以使用模擬框架來製作一個模擬'流'對象。但是,你可以用一個簡單的子類更容易地創建一個模擬的Stream對象。最重要的是,你在回答中說明了所有的嘲笑框架都是付費的,這顯然是不真實的。所以,即使你的答案的前半部分在技術上是真實的,你的答案也是誤導性的,你的答案暗示了「以艱難的方式」做事,而沒有指出或承認有一種更簡單的方法。這就是爲什麼其他堆棧溢出成員對它的評價很差的原因。 –

-1

我的解決方案是將Stream包裝在您自己的課程中讓我們將其命名爲StreamWrapper,它實現了接口IStream。現在改變導入簽名

public bool Import(IStream stream) 

現在你可以嘲笑那個流,如果你想在產品代碼中使用它,你應該通過StreamWrapper否則模擬。

+0

如何模擬任何有意義的數據流? – Raskolnikov

+0

這並不會幫助,因爲該方法顯然需要流中的Excel數據(請參閱GazTheDestroyer的回答)。 –

+0

@ user2451446它取決於Import方法的內容是什麼,使用什麼,期望什麼等 DavidArno我不明白你的意思是什麼?如果你包裝整個流類,你將能夠使用流提供的所有功能,但與另一個類,我不明白它會失敗。 – MistyK

相關問題