首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >有没有一种单元可测试的方法可以将文件上传到ASP.NET WebAPI?

有没有一种单元可测试的方法可以将文件上传到ASP.NET WebAPI?
EN

Stack Overflow用户
提问于 2012-08-22 07:53:12
回答 3查看 6.8K关注 0票数 18

我正在参与一个使用新的ASP.NET WebAPI的项目。我当前的任务是接受上传的文件。到目前为止,我已经使用测试驱动程序来驱动WebAPI代码,但是我在上传时遇到了困难。我目前正在遵循在http://www.asp.net/web-api/overview/working-with-http/sending-html-form-data,-part-2找到的建议,但似乎根本没有办法将其从单元测试中剔除。为了获取文件和表单数据,我必须使用MultipartFormDataStreamProvider,这是不可能模拟和/或覆盖的。除了放弃我的TDD方法,我还能做什么呢?

下面是示例中的代码:

代码语言:javascript
复制
public Task<HttpResponseMessage> PostFormData()
{
    // Check if the request contains multipart/form-data.
    if (!Request.Content.IsMimeMultipartContent())
    {
        throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
    }

    string root = HttpContext.Current.Server.MapPath("~/App_Data");
    var provider = new MultipartFormDataStreamProvider(root);

    // Read the form data and return an async task.
    var task = Request.Content.ReadAsMultipartAsync(provider).
        ContinueWith<HttpResponseMessage>(t =>
        {
            if (t.IsFaulted || t.IsCanceled)
            {
                Request.CreateErrorResponse(HttpStatusCode.InternalServerError, t.Exception);
            }

            // This illustrates how to get the file names.
            foreach (MultipartFileData file in provider.FileData)
            {
                Trace.WriteLine(file.Headers.ContentDisposition.FileName);
                Trace.WriteLine("Server file path: " + file.LocalFileName);
            }
            return Request.CreateResponse(HttpStatusCode.OK);
        });

    return task;
}

第一个问题是这一行:

代码语言:javascript
复制
var provider = new MultipartFormDataStreamProvider(root);

对于初学者来说,要对这段代码进行单元测试,我需要能够注入这样一个提供者。它在这个简单的构造函数调用中做了太多的事情,以至于无法在一行中“更新它”。一定有别的办法。(如果不是,WebAPI将失败)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-09-13 03:21:14

答案是“不”。ASP.NET是一个基于继承的框架。如果您正在尝试编写基于组合的应用程序,那么在某些时候,您会发现摩擦和障碍。是时候切换到像Nancy这样的东西了。

票数 -2
EN

Stack Overflow用户

发布于 2012-10-01 21:38:23

我抽象出了一个提供者包装器,这样我就可以模拟那些移动的部分,例如

代码语言:javascript
复制
    public interface IMultiPartFormDataStreamProviderWrapper : IDependency
    {
        string LocalFileName { get; }
        MultipartFormDataStreamProvider Provider { get; }
    }

    public class MultiPartFormDataStreamProviderWrapper : IMultiPartFormDataStreamProviderWrapper
    {
        public const string UploadPath = "~/Media/Default/Vocabulary/";
        private MultipartFormDataStreamProvider provider;

        public MultiPartFormDataStreamProviderWrapper(IHttpContextAccessor httpContextAccessor)
        {
            provider = new CustomMultipartFormDataStreamProvider(httpContextAccessor.Current().Server.MapPath(UploadPath));
        }

        public string LocalFileName
        {
            get { return provider.FileData[0].LocalFileName; }
        }


        public MultipartFormDataStreamProvider Provider
        {
            get { return provider; }
        }
    }

这样我就可以这样做了

代码语言:javascript
复制
    if (Request.Content.IsMimeMultipartContent())
    {
        return Request.Content.ReadAsMultipartAsync(provider.Provider).ContinueWith(t => 
                    {
                        if (t.IsCanceled || t.IsFaulted)
                            return (object)new { success = false };

不是很理想,但给了我一些想法。你认为如何?

票数 3
EN

Stack Overflow用户

发布于 2012-11-13 00:41:17

如果你还没有放弃使用Web,你可以尝试一下System.Net.Http.TestableMultipartStreamProviders,它是微软流提供者的一个插件重写。它们的好处是它们依赖于SystemWrapper进行文件操作,这意味着可以在单元测试中模拟文件操作。wiki给出了一些关于利用依赖注入来使测试控制器不那么痛苦的想法。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12064653

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档