2013-08-07 12 views
7

Jestem nowy w MOQ, ale używam go z NUnit do testowania jednostkowego.MOQ - Prześmiewanie Odpowiedź kontrolera MVC.Cookies.Clear()

Mam wszystkie części mojego kontrolera wyśmiewane, z wyjątkiem następującego wiersza, który zgłasza komunikat o błędzie "Obiekt nie został ustawiony na wystąpienie obiektu".

Response.Cookies.Clear(); 

Mam następującą metodę rozszerzenia do Mock kontekst kontrolera, który pracuje dla wszystkiego doszedłem po drugiej stronie tej pory (bardzo Dzięki dobrych ludzi na tym forum).

public static int SetUpForTest(this System.Web.Mvc.Controller ctl, string username, TestingUtility.Roles role) 
    { 
     var routes = new RouteCollection(); 
     MvcApplication.RegisterRoutes(routes); 

     var request = new Mock<HttpRequestBase>(MockBehavior.Strict); 
     request.SetupGet(x => x.ApplicationPath).Returns("/"); 
     request.SetupGet(x => x.Url).Returns(new Uri("http://localhost/a", UriKind.Absolute)); 
     request.SetupGet(x => x.ServerVariables).Returns(new System.Collections.Specialized.NameValueCollection()); 

     var response = new Mock<HttpResponseBase>(MockBehavior.Strict); 
     response.Setup(x => x.ApplyAppPathModifier(Moq.It.IsAny<String>())).Returns((String url) => url); 
     // response.SetupGet(x => x.Cookies).Returns(new HttpCookieCollection()); // This also failed to work 

     var context = new Mock<HttpContextBase>(MockBehavior.Strict); 
     context.SetupGet(x => x.Request).Returns(request.Object); 
     context.SetupGet(x => x.Response).Returns(response.Object); 
     context.SetupGet(x => x.Response.Cookies).Returns(new HttpCookieCollection()); // still can't call the Clear() method 

     // 
     // Mock the controller context (using the objects mocked above) 
     // 
     var moqCtx = new Mock<ControllerContext>(context.Object, new RouteData(), ctl); 
     moqCtx.SetupGet(p => p.HttpContext.User.Identity.Name).Returns(username); 
     moqCtx.SetupGet(p => p.HttpContext.User.Identity.IsAuthenticated).Returns(true); 
     if (!string.IsNullOrEmpty(role.ToString())) 
      moqCtx.Setup(p => p.HttpContext.User.IsInRole(role.ToString())).Returns(true); 

     // 
     // Pass the mocked ControllerContext and create UrlHelper for the controller and return 
     // 
     ctl.ControllerContext = moqCtx.Object; 
     ctl.Url = new UrlHelper(new RequestContext(context.Object, new RouteData()), routes); 
     return 1; 
    } 

Jak widać powyżej próbowałem wyśmiać "get" z kolekcji ciasteczek, co nie pomaga.

Nie można również wyśmiewać rzeczywistej metody Clear(), ponieważ nie jest to metoda wirtualna.

Oczywiście nie chcę testować, że pliki cookie są usuwane, po prostu chcę je zignorować podczas testowania.

Dzięki,

Greg

+0

Widzieliście to pytanie: http://stackoverflow.com/questions/1228179/mocking-httpcontextbase-with-moq – Halvard

+0

Dzięki za odpowiedź, ale przejrzałem przykłady w łączu i nie widziałem niczego, czego nie zrobiłem w szyderczym kontekście kontrolera powyżej. Jeśli czegoś brakuje, proszę wskazać mi właściwy kierunek! – Greg

+0

Jesteś pewny, że otrzymujesz zakodowany kontekst, a nie HttpContext.Current (na przykład) w tej części kodu? Tylko wyobrażenie, co może być nie tak. – JuhaKangas

Odpowiedz

14

To działa na mnie, gdy robię cookies.Clear()

  var request = new Mock<HttpRequestBase>(MockBehavior.Strict); 
     request.SetupGet(x => x.ApplicationPath).Returns("/"); 
     request.SetupGet(x => x.Url).Returns(new Uri("http://localhost/a", UriKind.Absolute)); 
     request.SetupGet(x => x.ServerVariables).Returns(new System.Collections.Specialized.NameValueCollection()); 

     var response = new Mock<HttpResponseBase>(MockBehavior.Strict); 
     response.Setup(x => x.ApplyAppPathModifier(Moq.It.IsAny<String>())).Returns((String url) => url); 
     // response.SetupGet(x => x.Cookies).Returns(new HttpCookieCollection()); // This also failed to work 

     var context = new Mock<HttpContextBase>(MockBehavior.Strict); 
     context.SetupGet(x => x.Request).Returns(request.Object); 
     context.SetupGet(x => x.Response).Returns(response.Object); 
     context.SetupGet(x => x.Response.Cookies).Returns(new HttpCookieCollection()); // still can't call the Clear() method 
     context.SetupGet(p => p.User.Identity.Name).Returns("blah"); 
     context.SetupGet(p => p.User.Identity.IsAuthenticated).Returns(true); 

     var rc = new RequestContext(context.Object, new RouteData()); 

     controller.ControllerContext = new ControllerContext(rc, controller); 
+0

Dziękuję - rozwiązaniem było tylko wyśmiać HttpContextBase, a nie ControllerContext, jak pokazano w przykładzie. Również dzięki Halvardowi za odpowiedź wskazującą mi właściwy kierunek – Greg

0

(To jest tylko pół odpowiedź, ale była zbyt duża dla pola komentarza ...)

Twój kpiący z new HttpCookieCollection()jest poprawna. Ten kod działa w separacji:

var request = new Mock<HttpRequestBase>(MockBehavior.Strict); 
request.SetupGet(x => x.ApplicationPath).Returns("/"); 
request.SetupGet(x => x.Url).Returns(new Uri("http://localhost/a", UriKind.Absolute)); 
request.SetupGet(x => x.ServerVariables).Returns(new System.Collections.Specialized.NameValueCollection()); 

var response = new Mock<HttpResponseBase>(MockBehavior.Strict); 
response.Setup(x => x.ApplyAppPathModifier(Moq.It.IsAny<String>())).Returns((String url) => url); 
// response.SetupGet(x => x.Cookies).Returns(new HttpCookieCollection()); // This also failed to work 

var context = new Mock<HttpContextBase>(MockBehavior.Strict); 
context.SetupGet(x => x.Request).Returns(request.Object); 
context.SetupGet(x => x.Response).Returns(response.Object); 
context.SetupGet(x => x.Response.Cookies).Returns(new HttpCookieCollection()); // still can't call the Clear() method 


// Here clearing the cookies works just fine: 
var instance = context.Object; 
instance.Response.Cookies.Clear(); 

Błąd nie istnieje, ale gdzieś indziej. Co się stanie, jeśli skomentujesz linię z numerem Response.Cookies.Clear()? Czy zatem wszystko inne jest wyśmiewane poprawnie? Kiedy debugujesz test, czy widzisz, że reszta makiety jest zgodna z oczekiwaniami? Byłbym zaskoczony, gdyby tak było (ale byłem zaskoczony przed ...).