MVC Mock HttpContextBase, который используется в помощнике - PullRequest
1 голос
/ 17 августа 2010

Я использую помощника в своих контроллерах и в своих представлениях, которые я нашел где-то в Интернете. Помощник вызывается так в моем контроллере "Url.SiteRoot ();" Как я могу заставить свой контроллер не генерировать исключение при вызове помощника? Я использую MVCContrib и moq для своих модульных тестов.

Я думаю о реализации какой-то проверки в помощнике, но похоже, что инфраструктура MVCContrib или moq должны быть в состоянии справиться с этим, чтобы мне не нужно было добавлять код исключения в мои помощники, чтобы иметь возможность пройти модульные тесты.

Вы можете увидеть код помощника здесь: -

namespace System.Web.Mvc {
public static class UrlHelpers {

    public static string SiteRoot(HttpContextBase context) {
        return SiteRoot(context, true);
    }

    public static string SiteRoot(HttpContextBase context, bool usePort) {
        var Port = context.Request.ServerVariables["SERVER_PORT"];
        if (usePort) {
            if (Port == null || Port == "80" || Port == "443")
                Port = "";
            else
                Port = ":" + Port;
        }
        var Protocol = context.Request.ServerVariables["SERVER_PORT_SECURE"];
        if (Protocol == null || Protocol == "0")
            Protocol = "http://";
        else
            Protocol = "https://";

        var appPath = context.Request.ApplicationPath;
        if (appPath == "/")
            appPath = "";

        var sOut = Protocol + context.Request.ServerVariables["SERVER_NAME"] + Port + appPath;
        return sOut;

    }

    public static string SiteRoot(this UrlHelper url) {
        return SiteRoot(url.RequestContext.HttpContext);
    }


    public static string SiteRoot(this ViewPage pg) {
        return SiteRoot(pg.ViewContext.HttpContext);
    }

    public static string SiteRoot(this ViewUserControl pg) {
        var vpage = pg.Page as ViewPage;
        return SiteRoot(vpage.ViewContext.HttpContext);
    }

    public static string SiteRoot(this ViewMasterPage pg) {
        return SiteRoot(pg.ViewContext.HttpContext);
    }

    public static string GetReturnUrl(HttpContextBase context) {
        var returnUrl = "";

        if (context.Request.QueryString["ReturnUrl"] != null) {
            returnUrl = context.Request.QueryString["ReturnUrl"];
        }

        return returnUrl;
    }

    public static string GetReturnUrl(this UrlHelper helper) {
        return GetReturnUrl(helper.RequestContext.HttpContext);
    }

    public static string GetReturnUrl(this ViewPage pg) {
        return GetReturnUrl(pg.ViewContext.HttpContext);
    }

    public static string GetReturnUrl(this ViewMasterPage pg) {
        return GetReturnUrl(pg.Page as ViewPage);
    }

    public static string GetReturnUrl(this ViewUserControl pg) {
        return GetReturnUrl(pg.Page as ViewPage);
    }
}
}

Ответы [ 3 ]

2 голосов
/ 18 августа 2010

Как пишет @ Джереми Фрей, вы получаете исключения, потому что вам не удается заглушить / подделать некоторые важные части HttpContext.

Как насчет использования:

Request.Url.GetLeftPart(System.UriPartial.Authority) 

вместо того, чтобы пытаться самостоятельно построить логику для создания URL? Если я правильно помню, он должен правильно подобрать протокол и порт, а также любой виртуальный каталог, сайт и т. Д.

0 голосов
/ 18 августа 2010

Этот код выглядит немного сложным.Я думаю, что это делает то же самое, и было бы намного проще проверить.(Я не уверен, почему так должно быть.)

public string FullApplicationPath(HttpRequestBase request)
{
    var path = request.Url.AbsoluteUri.Replace(request.Url.AbsolutePath,string.Empty);
    if (!string.IsNullOrEmpty(request.Url.Query))
    {
        path = path.Replace(request.Url.Query, string.Empty);
    }
    return path + request.ApplicationPath;
}
0 голосов
/ 17 августа 2010

Вы, вероятно, поняли, что причина, по которой вы получаете исключения из ваших методов расширения, заключается в нереализованных свойствах или методах в макетируемых объектах, например Запрос на HttpContextBase или RequestContext на UrlHelper.

Взгляните на некоторые из опубликованных стратегий здесь , чтобы узнать, как имитировать вызовы метода расширения. Лично я предпочитаю эту стратегию , которая позволит вам рефакторизовать ваши методы расширения для замены ставок во время исполнения.

Например, вместо:

public static class UrlHelperExtensions 
{
    public static string GetReturnUrl(this UrlHelper helper) 
    {
        return // your implementation of GetReturnUrl here
    }

}

Вы бы получили:

public interface IUrlHelperExtensions 
{
    string GetReturnUrl(UrlHelper helper);
}

public static class UrlHelperExtensions
{
    public static IUrlHelperExtensions Extensions(this UrlHelper target)
    {
        return UrlHelperExtensionFactory(target);
    }

    static UrlExtensions 
    {
        UrlHelperExtensionFactory = () => new DefaultUrlHelperExtensionStrategy();
    }

    public static Func UrlHelperExtensionFactory { get; set; }
}   

public DefaultUrlHelperExtensionStrategy : IUrlHelperExtensions 
{
    public string GetReturnUrl(UrlHelper helper) 
    {
        return // your implementation of GetReturnUrl here
    }
}

Вам нужно изменить способ вызова методов расширения с urlHelper.GetReturnUrl () на urlHelper.Extensions (). GetReturnUrl (), и во время модульного тестирования вы можете установить UrlHelperExtensions.UrlHelperExtensionFactory в качестве поддельного объект, но таким образом, вы можете контролировать поведение методов расширения во время теста.

...