【问题标题】:How to upload a file to an endpoint from an integration test如何从集成测试将文件上传到端点
【发布时间】:2011-07-01 18:49:50
【问题描述】:
当一个文件从客户端上传时,它可以在this.Request.Files中找到,它的类型是HttpFileCollectionBase。
HttpFileCollectionBase 包含 HttpPostedFileBase 条目。
这些对象的属性是只读的,所以我希望我可以设置一些模拟。我的模拟请求将返回一个模拟HttpFileCollection,并且该集合将包含一个模拟HttpPostedFile。该对象的InputStream 属性将返回一个FileStream 对象,我将使用源代码管理中的真实文件对其进行实例化。
- 这是上传的好方法吗
一个文件从一个端点到一个端点
集成测试?
- 如果这是一个好方法,我该如何模拟它
Moq?
- 如果这不是一个好方法,您能提出更好的方法吗?
谢谢!
【问题讨论】:
标签:
c#
asp.net-mvc
file-upload
moq
integration-testing
【解决方案1】:
我对 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 进行一个薄包装,即可按名称(或者您访问它们)获取文件流。这更好,因为下游代码现在依赖于UploadedFiles、Stream 和string,而不是HttpRequestBase、HttpFileCollectionBase、HttpPostedFileBase、Stream 和string。
然后设置将被简化为:
MemoryStream stream = new MemoryStream();
var mockUploadedFiles = new Mock<UploadedFiles>();
mockUploadedFiles.Setup(u => u.GetFile(It.IsAny<string>())).Returns(stream);