惩戒HttpPostedFileBase和的InputStream用于单元测试(Mocking Ht

2019-07-23 07:33发布

我想测试的代码下面一行:

...
Bitmap uploadedPicture = Bitmap.FromStream(model.Picture.InputStream) as Bitmap;
...

照片是在我的模型类型HttpPostedFileBase的属性。 所以我想嘲笑一个HttpPostedFileBase属性单元测试:

model.Picture = new Mock<HttpPostedFileBase>().Object;

一点问题都没有。

现在我有嘲笑的InputStream,否则就无效:

model.Picture.InputStream = new Mock<Stream>().Object;

这是不工作的InputStream的是只读的(还没有一个设置器方法):

public virtual Stream InputStream { get; }

是否有解决这个问题的好,清洁的方式? 一个解决办法是重写HttpPostedFileBase在我的单元测试派生类。 任何其他的想法?

Answer 1:

您好:)我不喜欢的东西,

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

        // Other stuff
    }

而就在测试本身,

    [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...
    }

希望这可以提供一个想法,你的解决方案:)



Answer 2:

我刚刚一直致力于类似的东西,并希望以下内容添加到@ TiagoC13的答案。

我的测试系统是我写的是测试一个文件的正确尺寸的要求之一的文件服务。 请注意,硬编码的文件名。 这存在在我的测试项目文件夹和文件。 该文件的属性如下:生成操作:嵌入式的资源,并复制到输出目录:复制,如果新的(虽然一直拷贝应该工作正常)

当项目是建立在testimage.jpg和文件夹添加到bin其中,测试,然后发现它。

还要注意fileStream.Close(); 这释放文件,这样就可以有许多在同一套件类似的测试。

希望这是帮助。

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();
    }


Answer 3:

有没有需要从磁盘上打开文件创建流。 其实我觉得这是一个非常可怕的解决方案。 一个工作流的测试,可以在内存中创建很轻松了。

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   
}        


文章来源: Mocking HttpPostedFileBase and InputStream for unit-test