5

T4MVCを使用するAsp.NetMVCアプリケーション用に、Watinを使用してスペックフローテストを作成しています。

テストで「マジックストリング」のURLを使用していることに気づきましたが、これは好きではありません。

[Given(@"I am on the sign up page")]
public void GivenIAmOnTheSignUpPage()
{
    string rootUrl = ConfigurationManager.AppSettings["RootUrl"];
    string fullUrl = string.Format("{0}/Authentication/Signup",rootUrl);
    WebBrowser.Current.GoTo(fullUrl);
}

MVCアプリで行うように、T4MVCアクション結果を使用したいのですが...

[Given(@"I am on the sign up page")]
public void GivenIAmOnTheSignUpPage()
{
    WebBrowser.Current.GoTo(MVC.Authentication.SignUp().ToAbsoluteUrl());
 }

私のToAbsoluteUrl拡張メソッド

public static class RouteHelper
{
    private static UrlHelper _urlHelper;
    private static string _rootUrl;

    public static string ToAbsoluteUrl(this ActionResult result)
    {
        EnsureUrlHelperInitialized();

        var relativeUrl = _urlHelper.Action(result);
        return string.Format("{0}/{1}", _rootUrl, relativeUrl);
    }

    private static void EnsureUrlHelperInitialized()
    {
        if (_urlHelper==null)
        {
            _rootUrl = ConfigurationManager.AppSettings["RootUrl"];

            var request = new HttpRequest("/", _rootUrl, "");
            var response = new HttpResponse(new StringWriter());
            var context = new HttpContext(request,response);
            HttpContext.Current = context;
            var httpContextBase = new HttpContextWrapper(context);


            RouteTable.Routes.Clear();
            MvcApplication.RegisterRoutes(RouteTable.Routes);

            var requestContext = new RequestContext(httpContextBase, RouteTable.Routes.GetRouteData(httpContextBase));

            _urlHelper = new UrlHelper(requestContext, RouteTable.Routes);
        }
    }
}

テストURLを生成できるようにRequestContextとRouteCollectionを初期化する正しい方法は何ですか?

現在、行でNullReferenceExceptionを受け取りますvar requestContext = new RequestContext(httpContextBase, RouteTable.Routes.GetRouteData(httpContextBase));。それはrequestContextを新しくする正しい方法ですか?

または、ActionResult(T4MVCから)を取得して、Webアプリの外部で絶対URLに解決するためのより良い方法がある場合は、それが本当に私が探しているものです。

4

1 に答える 1

5
public static class RouteHelper
{
    private static UrlHelper _urlHelper;
    private static string _rootUrl;

    static RouteHelper()
    {
        var routes = new RouteCollection();
        MvcApplication.RegisterRoutes(routes);
        var req = new HttpRequest(string.Empty, "http://www.site.com", null);
        var res = new HttpResponse(null);
        var ctx = new HttpContext(req, res); // do not use HttpContext.Current
        var requestContext = new RequestContext(new HttpContextWrapper(ctx), 
            new RouteData());
        _urlHelper = new UrlHelper(requestContext, routes);
        _rootUrl = ConfigurationManager.AppSettings["RootUrl"];
    }

    public static string ToAbsoluteUrl(this ActionResult result)
    {
        return string.Format("{0}{1}", _rootUrl, _urlHelper.Action(result));
    }
}

静的コンストラクターは、プライベートフィールドを設定します。静的なRouteTable.Routesプロパティを使用する代わりに、新しいRouteCollectionを使用することを選択しましたが、使用できる場合があります。

HttpRequestとHttpResponseのコンストラクターは重要ではないと思います。いくつかの文字列を渡して、例外をスローせずにそれらを構築できるようにしました。これらを使用して、まったく新しいHttpContextを構築します(xUnitから実行する場合はHttpContext.Currentを使用しないでください)。次に、それをHttpContextWrapperに入れて、HttpContextBase参照を取得できます。

新しいRequestContextを作成し、ベースラッパーと新しいRouteDataインスタンスを渡します。これを以前のRouteCollectionと一緒に使用して、UrlHelperを構築します。そのActionメソッドは「/」が前に付いた文字列を返すことに注意してください。そのため、RootUrl appSettingから除外する必要があります(したがって、末尾にスラッシュを付けずにvalue = "https://develop.site.com"のようなものを使用してください)。

これは、MVCエリアで定義されたルートでは機能しないことに注意してください。そのためには、グローバルasaxでRegisterRoutesを呼び出すことに加えて、エリアを登録する必要があります。

于 2012-05-08T19:42:03.737 に答える