Pytanie Poszukując kierunku na jednostce testowanie rozszerzenia kontrolera, które renderuje częściowy widok


Jak mówi tytuł, szukam wskazówek, jak poprawnie przetestować rozszerzenie kontrolera. Rozszerzenie renderuje częściowy widok, którego z kolei używam w ramach JSONResult:

 public static string RenderPartialViewToString(this Controller controller, string viewName = null, object model = null)
        {
            if (string.IsNullOrEmpty(viewName))
            {
                viewName = controller.ControllerContext.RouteData.GetRequiredString("action");
            }

            controller.ViewData.Model = model;

            using (StringWriter sw = new StringWriter())
            {
                ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName);
                ViewContext viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw);
                viewResult.View.Render(viewContext, sw);
                return sw.GetStringBuilder().ToString();
            }
        }

Przykładowe użycie:

public JsonResult Foo()
{
    var model = _repository.getSomeData();

    return Json(new { html = this.RenderPartialViewToString("Index", model) }, JsonRequestBehavior.AllowGet);
}

Używam NUnit i Pomocnik testowy MvcContribjednak podczas konfigurowania kontrolera, który korzysta z tego rozszerzenia, uruchamiam NRE. Zakładam, że kontekst kontrolera nie jest poprawnie skonfigurowany?

Ostatecznie test jest przerwany ViewEngines.Engines.FindPartialView. Oto część niepowodzenia testu:

var routeData = new RouteData();
routeData.Values.Add("controller", "someName");
routeData.Values.Add("action", "someAction");

var builder = new TestControllerBuilder();
var controller = new ListingController(repository.Object);
builder.RouteData = routeData;
builder.InitializeController(controller);

var result = controller.Foo();

13
2018-01-14 00:33


pochodzenie




Odpowiedzi:


Będziesz musiał dodać silnik widoku wyśmiewanego do ViewEngines.Engines kolekcja, aby można było sfałszować wywołanie FindPartialView. Oto przykład z Rhino Mocks:

var view = MockRepository.GenerateStub<IView>();
var engine = MockRepository.GenerateStub<IViewEngine>();
var viewEngineResult = new ViewEngineResult(view, engine);
engine
    .Stub(x => x.FindPartialView(null, null, false))
    .IgnoreArguments()
    .Return(viewEngineResult);
ViewEngines.Engines.Add(engine);

Następnie możesz stwierdzić, że wywołano metodę view.Render, przechwycić jej argumenty i napisać kilka wyśmiewających danych do tego programu piszącego i ostatecznie potwierdzić, że działanie kontrolera zwróciło ten wyśmiewany ciąg.


22
2018-01-14 09:00



Po prostu uderzyłem się w czoło i zacytowałem reklamę V8. Doh! Dziękuję za wskazanie tego, czego nie widziałem. Dla pewności jestem poważny, nie żartuję. - Andrew Steitz
thanx, użyte to samo podejście, ale tylko z Moq framework. - Alex M
W MVC4, może być konieczne zrobienie ViewEngines.Engines.Clear () przed dodaniem silnika próbnego. Przynajmniej to było to, co musiałem zrobić, aby to działało po aktualizacji z MVC3 do MVC4. - antinescience
@antinescience Musiałem zrobić to samo w MVC3, dzięki. - Pawel Krakowiak