2010-08-15 6 views
9

Ich muss HttpContext.Current.Application Tabelle vortäuschen, um von meinen Komponententests darauf zuzugreifen.Wie kann ich HttpContext für Komponententests fälschen?

Ich muss meine Daten irgendwo speichern. Ich dachte, dass ich nur Instanz NameValueCollectionBase übergeben kann, aber als ich entdeckte, dass dieser Basistyp keinen Indexer hat, scheint es zu kompliziert zu verwenden.

Also, was ist mit diesem Teil von HttpContext? Ist es möglich? Wie kann ich es schaffen? Wird NUnit.Mocks hilfreich sein?

Vielen Dank im Voraus ...

Antwort

1

Wenn Sie Indizes für Namevaluecollection Basis unter Code bitte

public static IEnumerable<KeyValuePair<string, string>> ToPairs(this NameValueCollection collection) 
{ 
    if(collection == null) 
    { 
     throw new ArgumentNullException("collection"); 
    } 

    return collection.Cast<string>().Select(key => new KeyValuePair<string, string>(key, collection[key])); 
} 

für die Verwendung nur Daten zu speichern und vorbei um Testmethoden bitte Verwenden Sie den obigen Code.

2
+0

Problem ist, dass, wenn es über 'User' ist, es einfach ist, neues Objekt vom Typ' IPrincipal' zurückzugeben, aber wenn es zu 'Application' kommt, dann muss ich ein' HttpApplicationState'-Objekt zurückgeben, das keinen öffentlichen Konstruktor hat und wegen der Verwendung von Indexern ist es schwierig, mit 'NUnit.Mocks' zu fälschen ... Können Sie mir ein Codebeispiel für diesen Fall geben? –

+0

Hallo, Wenn Sie Indizes für Namevaluecollection Basis benötigen Sie bitte die folgenden Code public static IEnumerable > ToPairs (diese Namevaluecollection-Sammlung) { if (Sammlung == null) { throw new verwenden ArgumentNullException ("Sammlung"); } Rückgabe collection.Cast () .Wählen Sie (key => new KeyValuePair (Schlüssel, Sammlung [key])); } Wenn Sie nur Daten speichern und Testmethoden weitergeben möchten, verwenden Sie den obigen Code. – Venkat

+2

erste Verbindung funktioniert nicht –

0

In diesem Szenario erzeuge ich einige Stubs von den Basisklassen in System.Web.Abstractions abgeleitet. Ich benutze oft diese Technik für MVC-Anwendungen wie MVC/WebAPI Controller eine Abstraktion zu Httpcontext enthalten (Httpcontextbase)

So kann ich Httpcontext Anforderungen in meiner Einheit/Integrationstests Stub kann, ist hier eine Probe ...

public class MockHttpApplicationState : HttpApplicationStateBase 
{ 
    private IDictionary<string, object> _appState = new Dictionary<string, object>(); 

    public override void Add(string name, object value) 
    { 
     _appState.Add(name, value); 
    } 

    public override object Get(string name) 
    { 
     return _appState[name]; 
    } 

    public override object this[string name] 
    { 
     get 
     { 
      return _appState[name]; 
     } 

     set 
     { 
      _appState[name] = value; 
     } 
    } 
} 

public class MockHttpContext : HttpContextBase 
{ 
    private IDictionary<string, object> _appKeys; 

    public MockHttpContext() 
    { 

    } 

    /// <summary> 
    /// Accepts a dictionary of app keys to supply to the HttpApplicationState instance 
    /// </summary> 
    /// <param name="applicationState"></param> 
    public MockHttpContext(IDictionary<string,object> applicationState) 
    { 
     _appKeys = applicationState; 
    } 

    public override Cache Cache 
    { 
     get 
     {     
      return HttpRuntime.Cache; 
     } 
    } 

    public override HttpApplicationStateBase Application 
    { 
     get 
     { 
      var mockAppState = new MockHttpApplicationState(); 

      foreach (string key in _appKeys.Keys) 
      { 
       mockAppState.Add(key, _appKeys[key]); 
      } 

      return mockAppState; 
     } 
    } 

    public override HttpRequestBase Request 
    { 
     get 
     { 
      return new HttpRequestWrapper(new HttpRequest(null,"http://localhost",null)); 
     } 
    } 
} 

Dann kann mein Test-Controller etablieren und Http Kontext:

private readonly OnlineShop.MVC.Controllers.HomeController _controller = 
     new MVC.Controllers.HomeController(null,new UnitOfWork()); 

    [OneTimeSetUp] 
    public void Init() 
    { 
     var appKeys = new Dictionary<string, object>(); 

     appKeys.Add("localhost", 1); 

     var httpContext = new MockHttpContext(appKeys); 

     _controller.ControllerContext = new ControllerContext() 
     { 
      Controller = _controller, 
      RequestContext = new RequestContext(httpContext, new RouteData())  
     };       
    } 

    [Test] 
    public void Index_Returns_HomeView() 
    {    
     var view = _controller.Index() as ViewResult; 
     var viewModel = view.Model as MVC.ViewModels.Home; 

     Assert.IsInstanceOf<OnlineShop.MVC.ViewModels.Home>(viewModel); 
     Assert.IsTrue(viewModel.FeaturedProducts.Count > 0); 
    } 

und mein Controller ist davon bewusst ist Umgebungshttpcontextbase-Instanz liefert Cache und Anwendungsstatus:

public ActionResult Index() 
    {       
     string cacheKey = string.Format("FeaturedProducts-{0}",WebsiteId); 
     IList<Product> productList = this.HttpContext.Cache[cacheKey] as IList<Product>; 


     //My app keeps a list of website contexts in the Application. This test returns 1 based on the unit/int tests or a real world db value when hosted on IIS etc.. 
     int websiteId = (int)HttpContext.Application[this.Request.Url.Host];