Mocking HttpPostedFileBase and InputStream for unit-test

喜你入骨 提交于 2019-11-27 22:48:30
TiagoC13

Hi there :) I did something like,

    [TestInitialize]
    public void SetUp()
    {
        _stream = new FileStream(string.Format(
                        ConfigurationManager.AppSettings["File"],
                        AppDomain.CurrentDomain.BaseDirectory), 
                     FileMode.Open);

        // Other stuff
    }

And on the Test itself,

    [TestMethod]
    public void FileUploadTest() 
    {
        // Other stuff

        #region Mock HttpPostedFileBase

        var context = new Mock<HttpContextBase>();
        var request = new Mock<HttpRequestBase>();
        var files = new Mock<HttpFileCollectionBase>();
        var file = new Mock<HttpPostedFileBase>();
        context.Setup(x => x.Request).Returns(request.Object);

        files.Setup(x => x.Count).Returns(1);

        // The required properties from my Controller side
        file.Setup(x => x.InputStream).Returns(_stream);
        file.Setup(x => x.ContentLength).Returns((int)_stream.Length);
        file.Setup(x => x.FileName).Returns(_stream.Name);

        files.Setup(x => x.Get(0).InputStream).Returns(file.Object.InputStream);
        request.Setup(x => x.Files).Returns(files.Object);
        request.Setup(x => x.Files[0]).Returns(file.Object);

        _controller.ControllerContext = new ControllerContext(
                                 context.Object, new RouteData(), _controller);

        // The rest...
    }

Hope this can provide an idea to your solution :)

I've just been working on something similar and wanted to add the following to @TiagoC13's answer.

My system under test was a file service I'm writing, one of the requirements being to test that a file has the correct dimensions. Note, the hard-coded filename. This exists as a folder and file in my Test Project. The file's properties are as follows: Build Action : Embedded Resource and Copy to Output Directory: Copy if newer (although Copy Always should work OK)

When the project is built the testimage.jpg and its folder are added to the bin where the test then finds it.

Also note the fileStream.Close(); this releases the file so you can have a number of similar tests in the same suite.

Hope this is of help.

using Moq;
using NUnit.Framework;
using System.Web;

    [Test]
    public void IsValidFile() {
        string filePath = Path.GetFullPath(@"testfiles\testimage.jpg");
        FileStream fileStream = new FileStream(filePath, FileMode.Open);
        Mock<HttpPostedFileBase> uploadedFile = new Mock<HttpPostedFileBase>();

        uploadedFile
            .Setup(f => f.ContentLength)
            .Returns(10);

        uploadedFile
            .Setup(f => f.FileName)
            .Returns("testimage.jpg");

        uploadedFile
            .Setup(f => f.InputStream)
            .Returns(fileStream);

        var actual = fileSystemService.IsValidImage(uploadedFile.Object, 720, 960);

        Assert.That(actual, Is.True);

        fileStream.Close();
    }
fearofawhackplanet

There is no need to create a stream from opening a file on disk. Actually I think that's a pretty horrible solution. A working test stream can be created easily enough in-memory.

var postedFile = new Mock<HttpPostedFileBase>();

using (var stream = new MemoryStream())
using (var bmp = new Bitmap(1, 1))
{
    var graphics = Graphics.FromImage(bmp);
    graphics.FillRectangle(Brushes.Black, 0, 0, 1, 1);
    bmp.Save(stream, ImageFormat.Jpeg);

    postedFile.Setup(pf => pf.InputStream).Returns(stream);

    // Assert something with postedFile here   
}        
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!