When a file is uploaded from the client, it can be found in this.Request.Files
, which is of type HttpFileCollectionBase
.
HttpFileCollectionBase
contains HttpPostedFileBase
entries.
The properties on these objects are read-only, so I was hoping I could setup some mocks. My mock request would return a mock HttpFileCollection
, and that collection would contain one mockHttpPostedFile
. The InputStream
property on that object would return a FileStream
object that I would instantiate using a real file in source control.
- Is this a good app开发者_运维百科roach to uploading a file to an endpoint from an integration test?
- If it is a good approach, how can I mock this out
with
Moq
? - If this is not a good approach, can you suggest a better way?
Thanks!
I know nothing about asp.net mvc, but it looks like you would need to do something like this to setup your mock dependencies:
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
In a unit test, I would use a memory stream rather a file, but a file stream works the same.
If you want to avoid having to mock out and set up all these dependencies, you could put them behind a UploadedFiles
abstraction, make your code depend on the abstraction, and mock only UploadedFiles
. This need only be a thin wrapper around Request.Files
to get a file stream by name (or however you access them). This is better because the downstream code now depends on UploadedFiles
, Stream
and string
, rather than HttpRequestBase
, HttpFileCollectionBase
, HttpPostedFileBase
, Stream
and string
.
Setup would then be simplified to something like this:
MemoryStream stream = new MemoryStream();
var mockUploadedFiles = new Mock<UploadedFiles>();
mockUploadedFiles.Setup(u => u.GetFile(It.IsAny<string>())).Returns(stream);
精彩评论