2012-05-08 23 views
5

Tôi đang viết kiểm tra luồng thông tin bằng cách sử dụng Watin, cho ứng dụng Asp.Net MVC sử dụng T4MVC.Sử dụng các tuyến Asp.Net MVC từ một ứng dụng không phải trên web (các bài kiểm tra)

Tôi thấy mình đang sử dụng url "chuỗi ma thuật" trong các bài kiểm tra mà tôi không thích.

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

tôi nhiều thà sử dụng kết quả T4MVC hành động của tôi như tôi làm trong App MVC, một cái gì đó như thế này ...

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

My Extension Method 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); 
     } 
    } 
} 

là gì cách chính xác để khởi tạo RequestContext và RouteCollection để tôi có thể tạo URL thử nghiệm của mình?

Hiện tại tôi nhận được NullReferenceException trên dòng var requestContext = new RequestContext(httpContextBase, RouteTable.Routes.GetRouteData(httpContextBase));. Đó có phải là cách đúng để tạo mới một requestContext không?

Hoặc nếu có cách nào tốt hơn để thực hiện ActionResult (từ T4MVC) và giải quyết nó thành url tuyệt đối, bên ngoài ứng dụng web, đó thực sự là những gì tôi đang tìm kiếm.

+0

Bạn đang sử dụng lib thử nghiệm đơn vị nào với SpecFlow? MsTest, NUnit, hay cái gì khác? – danludwig

+0

Tôi đang sử dụng xUnit, điều đó có quan trọng không? – Brook

+0

Không, tôi đã tự hỏi nên tôi có thể tùy chỉnh câu trả lời của mình. Tôi không chắc chắn những gì tương đương xunit cho [TestClass] và [AssemblyInitialize], nhưng hãy tưởng tượng nó không khó để tìm ra. – danludwig

Trả lời

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

Trình tạo tĩnh thiết lập trường riêng của bạn. Tôi đã chọn sử dụng một RouteCollection mới, thay vì sử dụng thuộc tính RouteTable.Routes tĩnh, nhưng bạn có thể có.

Tôi không nghĩ rằng các nhà thầu cho vấn đề HttpRequest và HttpResponse. Tôi chỉ cần vượt qua trong một số dây để có được chúng để xây dựng mà không ném một ngoại lệ. Sử dụng chúng để xây dựng một HttpContext mới (không sử dụng HttpContext.Current khi chạy từ xUnit). Sau đó bạn có thể đặt nó vào một HttpContextWrapper để lấy tham chiếu HttpContextBase của bạn.

Tạo một RequestContext mới, chuyển vào trình bao bọc cơ sở của bạn và một phiên bản RouteData mới. Sử dụng điều đó, cùng với RouteCollection trước đó của bạn để xây dựng UrlHelper. Lưu ý rằng phương thức Action của nó sẽ trả về các chuỗi được thêm vào trước với "/", vì vậy bạn nên để nó ra khỏi ứng dụng RootUrl của chúng ta (vì vậy hãy sử dụng một cái gì đó giống như value = "https://develop.site.com" mà không có dấu gạch chéo).

Lưu ý rằng điều này sẽ không hoạt động đối với các tuyến được xác định trong các khu vực MVC. Đối với điều đó, bạn cần phải đăng ký các khu vực ngoài việc gọi RegisterRoutes trong asax toàn cầu.

+0

Điều đó đã làm điều đó, cảm ơn. Tôi đã thay đổi nó để sử dụng phương thức "Ensure" thay vì initializer kiểu mặc dù, vì chúng có xu hướng ném các ngoại lệ rất lạ khi các vấn đề xảy ra, và cho rằng đây là đọc từ cấu hình, điều đó có khả năng xảy ra. – Brook

+0

Thật là một phao cứu sinh bạn .. Tôi googled cho điều này trong nhiều giờ –