2012-05-08 14 views
5

T4MVC kullanan bir Asp.Net MVC uygulaması için Watin kullanarak specflow testleri yazıyorum.Web dışı bir uygulamadan Asp.Net MVC Yollarını Kullanma (testler)

Kendimi beğenmediğim testlerde "magic string" URL'leri kullanarak buluyorum.

[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); 
} 
Ben MVC Uygulaması'nda böyle bir şey yapmak gibi ben daha ziyade benim T4MVC Eylem Sonuçları kullanırsınız

... nedir

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

Benim ToAbsoluteUrl Uzatma Yöntemi

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

Test URL'lerimi oluşturabilmem için RequestContext ve RouteCollection'ı başlatmanın doğru yolu?

Şu anda var requestContext = new RequestContext(httpContextBase, RouteTable.Routes.GetRouteData(httpContextBase)); numaralı hatta bir NullReferenceException alıyorum. RequestContext'i güncellemenin doğru yolu bu mu? Veya bir ActionResult (T4MVC'den) almak ve onu bir web uygulamasının dışında mutlak bir URL'ye çözmek için daha iyi bir yol varsa, gerçekten aradığım şey budur.

+0

SpecFlow ile hangi birim test lib'yi kullanıyorsunuz? MsTest, NUnit, ya da başka bir şey? – danludwig

+0

xUnit kullanıyorum, fark eder mi? – Brook

+0

Hayır, merak ettim ki cevabımı özelleştirebildim. Xunit eşdeğerlerinin [TestClass] ve [AssemblyInitialize] için ne olduğundan emin değilim, ancak bunun zor olmadığını hayal edin. – danludwig

cevap

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

Statik kurucu, özel alanlarınızı ayarlar. Statik RouteTable.Routes özelliğini kullanmak yerine yeni bir RouteCollection kullanmayı tercih ettim, ancak yapabiliyor olabilirsiniz.

HttpRequest ve HttpResponse konusundaki kurucuları sanmıyorum. Bir istisna atmadan inşa etmelerini sağlamak için bazı dizelerden geçtim. Yepyeni bir HttpContext oluşturmak için kullanın (xUnit'ten çalışırken HttpContext.Current kullanmayın). Sonra HttpContextBase referansınızı almak için bir HttpContextWrapper içine koyabilirsiniz.

Yeni bir RequestContext oluşturun, temel sarıcınızı ve yeni bir RouteData örneğini geçirin. UrlHelper'ı oluşturmak için önceki RouteCollection ile birlikte kullanın. Eylem yönteminin "/" ile harmanlanmış dizeleri döndüreceğine dikkat edin, bu nedenle RootUrl appSetting'inizden çıkmalısınız (böylelikle değer eğik çizgisi olmadan "https://develop.site.com" gibi bir değer kullanın).

Not Bu, MVC alanlarında tanımlanan yollarda çalışmayacaktır. Bunun için, global asax'da RegisterRoutes'u çağırmanın yanı sıra alanları da kaydetmeniz gerekir.

+0

Bunu yaptı, teşekkürler. Ancak, tür başlatıcı yerine "emin ol" yöntemini kullanmak için değiştirdim, çünkü bu sorunlar ortaya çıktığında çok garip istisnalar atma eğilimi ve bu yapılandırmadan okunması göz önüne alındığında, bunun olması muhtemeldir. – Brook

+0

Ne cehennemdesin .. Saatlerce bunun için googled –

İlgili konular