2009-06-29 18 views
14

Potrzebujesz kilku wskazówek na ten temat. Znalazłem this i this, ale nadal jestem trochę zmieszany.Jak przetestować filtry akcji w ASP.NET MVC?

Po prostu chcę sfałszować ActionExecutedContext, przekazać go, pozwolić filtrować do pracy i sprawdzić wynik.

Każda pomoc?

Źródło filtra można znaleźć here
(trochę się zmieniło, ale to nie jest w tej chwili).

Chcę przetestować jednostkę, czy filtr RememberUrl jest wystarczająco inteligentny, aby zapisać bieżący URL w sesji.

+0

ActionExecutedContext pochodzi z ControllerContext. Odpowiedź Haackeda dotyczy właśnie kpiny z ControllerContext - http://stackoverflow.com/questions/32640/mocking-asp-net-mvc-controller-context/32672#32672. W czym dokładnie jesteś zdezorientowany? –

+0

Po prostu jeszcze tego nie zrobiłem. Chyba brakuje mi wiedzy na temat innerworkings asp.net mvc. :) –

+0

Następnie opublikuj swój kod. Postaramy się pomóc :) –

Odpowiedz

11

1) Mocking Request.Url w ActionExecutedContext:

var request = new Mock<HttpRequestBase>(); 
request.SetupGet(r => r.HttpMethod).Returns("GET"); 
request.SetupGet(r => r.Url).Returns(new Uri("http://somesite/action")); 

var httpContext = new Mock<HttpContextBase>(); 
httpContext.SetupGet(c => c.Request).Returns(request.Object); 

var actionExecutedContext = new Mock<ActionExecutedContext>(); 
actionExecutedContext.SetupGet(c => c.HttpContext).Returns(httpContext.Object); 

2) Załóżmy, że wstrzykiwanie opakowanie sesyjne w swojej RememberUrlAttribute za konstruktora publicznego.

var rememberUrl = new RememberUrlAttribute(yourSessionWrapper); 

rememberUrl.OnActionExecuted(actionExecutedContext.Object); 

// Then check what is in your SessionWrapper 
+0

RememberUrl nie ma metody "ActionExecutedCotnext". –

+0

To OnActionExecuted. W każdym razie - wydaje się, że w końcu to dostałem. Wystarczy poprawnie kpić z httpContext. Jeszcze raz dziękuję - naprawdę doceniam Twoją pomoc. :) –

+0

....... Naprawiono :) –

3

Jest to wynikiem:

#region usages 

using System; 
using System.Collections.Specialized; 
using System.Web; 
using System.Web.Mvc; 
using x.TestBase; 
using x.UI.y.Infrastructure.Enums; 
using x.UI.y.Infrastructure.Filters; 
using x.UI.y.Test.Mocks; 
using Moq; 

//considering switch to NUnit... :D 
using Microsoft.VisualStudio.TestTools.UnitTesting; 

#endregion 

namespace x.UI.y.Test.Unit.Infrastructure.Filters 
{ 
    [TestClass] 
    public class RememberUrlTester : TesterBase 
    { 
     private static HttpContextBaseMock _context = 
      new HttpContextBaseMock(); 
     private static ActionExecutedContextMock _actionContext = 
      new ActionExecutedContextMock(_context.Object); 

     [TestMethod] 
     //"Can save url in session" (i prefer test names in my own language :) 
     public void SpeejPieglabaatUrlSesijaa() 
     { 
      //Arrange 
      const string _url = "http://www.foo.bar/foo?bar=bar"; 
      _context.RequestMock.SetUrl(_url);  
      var filter = new RememberUrlAttribute(); 

      //Act 
      filter.OnActionExecuted(_actionContext.Object); 

      //Assert 
      _context.SessionMock.Verify 
       (m => m.Add(SessionKey.PreviousUrl.ToString(), _url)); 
     } 
    } 
} 

Owinięty Mock <HttpWhatever> zachować testy czyste.

Jestem pewien, że można zrobić coś lepiej, ale myślę, że to świetny początek i jestem podekscytowany.

Wreszcie, że potwór HttpContext jest pod kontrolą! ^^

+0

Jeśli to działa dla ciebie, to jest fajne, ale ludzie z xUnit napisali o tym, dlaczego go zbudowali, co jest warte przeczytania: http://xunit.codeplex.com/wikipage ? title = WhyDidWeBuildXunit & referringTitle = Home – ZeroBugBounce

+0

@richdiet ten był dawno temu. Wolałbym teraz xUnit. –

Powiązane problemy