2015-05-13 27 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

相关问题