Получить имя представления, где ViewResult.ViewName - пустая строка для модульного тестирования. - PullRequest
5 голосов
/ 29 ноября 2011

Я написал метод расширения для ActionResult для использования в модульном тестировании, который будет утверждать, что возвращаемое ViewName соответствует ожидаемому. Вот код, который у меня есть:

public static void AssertViewWasReturned(this ActionResult result, string viewName)
{
    string actualViewName;

    if (result is ViewResult)
        actualViewName = (result as ViewResult).ViewName;
    else if (result is PartialViewResult)
        actualViewName = (result as PartialViewResult).ViewName;
    else
        throw new InvalidOperationException("Results of type " + result.GetType() + " don't have a ViewName");

    Assert.AreEqual(viewName, actualViewName, string.Format("Expected a View named{0}, got a View named {1}", viewName, actualViewName));
}

Это работает нормально, за исключением случаев, когда контроллер возвращает View без указания имени - в этом случае result.ViewName - пустая строка.

Итак, мой вопрос - есть ли смысл сообщать объекту ViewResult, какое имя у View было, где ViewName - пустая строка?

Ответы [ 6 ]

6 голосов
/ 29 ноября 2011

Если ваш метод контроллера не вызывается через конвейер MVC, дополнительная информация не добавляется в словарь Controller.ViewData (который, как я предполагал, каким-то образом предоставит клавишу "action", но не сможет подтвердить). Но поскольку вы используете свой контроллер «вне» контекста платформы маршрутизации и т. Д., Он никак не может знать о вызываемом методе.

Так что ответ просто «нет». Если имя представления не было указано, вы не можете определить его по ViewResult, возвращенному действием. По крайней мере, не в том, как тестируется ваш контроллер (кстати, это вполне нормально).

4 голосов
/ 30 ноября 2011

Для чего это стоит - я пересмотрел свой тест моего метода расширения следующим образом (с учетом обратной связи Дж. Тихона):

public static void AssertViewWasReturned(this ActionResult result, string viewName, string defaultViewName)
{    
    Assert.IsInstanceOf<ViewResultBase>(result, "Result is not an instance of ViewResultBase");
    var viewResult = (ViewResultBase)result;

    var actualViewName = viewResult.ViewName;

    if (actualViewName == "")
        actualViewName = defaultViewName;

    Assert.AreEqual(viewName, actualViewName, string.Format("Expected a View named{0}, got a View named {1}", viewName, actualViewName));
}

Это означает, что мои модульные тесты могут содержать код, подобный этому:

var result = controller.MyAction();
result.AssertViewWasReturned("ExpectedViewName","MyAction")

Это не так хорошо, как я надеялся, так как мне нужно указать 'defaultViewName' (то есть имя действия), но это разумный компромисс.

2 голосов
/ 29 ноября 2011

Вы можете обновить свои контроллеры, чтобы всегда передавать желаемое представление.

Вместо:

public ActionResult Index()
{
    return View();
}

Сделайте это вместо:

public ActionResult Index()
{
    return View("Index");
}

Либо так, либо измените код модульного теста.

1 голос
/ 11 октября 2015

Вы должны назвать имя вашего вида при возвращении.

Пример:

Public ActionResult Index(){

// your code

Return View("YourViewName", DataToSendForView);
}
1 голос
/ 29 ноября 2011

Не уверен, что я понимаю ваш вопрос, но если метод View() вызывается без параметров, MVC будет искать представление с именем метода вызывающего действия в каталоге с именем Controller (без " Добавлен суффикс «имя контроллера»).

Например, это действие:

public class UserController : Controller
{
    public ActionResult SomeAction()
    {
        // some code here
        return View();
    }
}

Поскольку это пустой View() вызов, MVC будет искать представление с путем и именем файла ~\Views\User\SomeAction.cshtml.

Это отвечает на ваш вопрос?

0 голосов
/ 09 марта 2012

Вы можете переопределить контроллер. OnResultExecuted Метод - это точка в жизненном цикле контроллера, где доступно представление.

protected override void OnResultExecuted(ResultExecutedContext ctx)
{
    base.OnResultExecuted(ctx);
    String ViewPath = ((System.Web.Mvc.BuildManagerCompiledView)((System.Web.Mvc.ViewResultBase)ctx.Result).View).ViewPath.ToString();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...