如何从集成测试将文件上载到端点

时间:2011-07-01 18:49:50

标签: c# asp.net-mvc file-upload moq integration-testing

从客户端上传文件时,可以在this.Request.Files HttpFileCollectionBase中找到该文件。

HttpFileCollectionBase包含HttpPostedFileBase条目。

这些对象的属性是只读的,所以我希望我可以设置一些模拟。我的模拟请求将返回一个模拟HttpFileCollection,该集合将包含一个模拟HttpPostedFile。该对象上的InputStream属性将返回一个FileStream对象,我将使用源代码管理中的真实文件进行实例化。

  1. 这是上传的好方法吗? 一个文件到一个端点 整合测试?
  2. 如果这是一个好方法,我怎么能嘲笑这个 与Moq
  3. 如果这不是一个好方法,你能建议一个更好的方法吗?
  4. 谢谢!

1 个答案:

答案 0 :(得分:4)

我对asp.net mvc一无所知,但看起来你需要做这样的事情来设置你的模拟依赖项:

MemoryStream stream = new MemoryStream();

var mockFile = new Mock<HttpPostedFileBase>();
var mockFiles = new Mock<HttpFileCollectionBase>();
var mockRequest = new Mock<HttpRequestBase>();

mockFile.Setup(f => f.InputStream).Returns(stream);

// if for example, you index the file by name.
mockFiles.Setup(f => f[It.IsAny<string>()]).Returns(mockFile.Object);

mockRequest.Setup(r => r.Files).Returns(() => mockFiles.Object);

// write expected data to your memory stream, then instantiate your class 
// under test using the mockRequest.Object

在单元测试中,我会使用内存流而不是文件,但文件流的工作方式相同。

如果你想避免模拟并设置所有这些依赖项,你可以将它们置于UploadedFiles抽象之后,使代码依赖于抽象,并仅模拟UploadedFiles。这只需要Request.Files周围的瘦包装器来获取文件流的名称(或者您访问它们)。这样做更好,因为下游代码现在取决于UploadedFilesStreamstring,而不是HttpRequestBaseHttpFileCollectionBaseHttpPostedFileBase,{{ 1}}和Stream

然后将设置简化为以下内容:

string