Reputation: 3438
I want to test some controller actions whose views contain Html.Action with PartialViews. But when debugging them I don't get the breakpoint that is in the action that I want to call through the view.
Here is my controller code:
public class SomeController
{
public ActionResult MyAction()
{
return View();
}
public PartialViewResult SubAction()
{
return PartialView();
}
}
The code in the MyAction view is simply:
@{
ViewBag.Title = "MyAction";
}
@Html.Action("SubAction")
With my TestMethod I'd like to check if the correct ViewName is returned:
[TestMethod]
public void MyActionTest()
{
SomeController controller = new SomeController();
ViewResult result = controller.MyAction() as ViewResult;
Assert.IsNotNull(result, "The result is not a view result.");
Assert.AreEqual("some expected name", result.ViewName);
}
Another problem is that the result.ViewName is empty here and I don't know why that is. So this is another question unanswered. That problem is why I tried to debug my unit test and recognized that I cannot break into SubAction().
Any suggestions about that?
Cheers,
Simon
Upvotes: 0
Views: 2621
Reputation: 39501
ViewResult
, and more generally, ActionResult
is some kind of specification of what to execute when returning results to client. In other words, creating an instance of it (returning View() from controller) does create specification, but not execute it. MVC runtime captures that ActionResult returned from controller and Execute()s
it. You cannot break inside the view because it is not executed yet - specification is just created. If you would have called Execute()
method on it, as does mvc runtime, you would trigger view execution and hit the debugger. ViewResult.ViewName gets or sets the name of the view to render.
And if you do not set it when returning View, it is only populated when the ViewResult is Executed()
, see the explanation above.
You should only test controller and its iteraction with views, repositories, etc. when unit testing controller. You should not need to debug the view when testing controller. If you need to test SubAction, write the separate test for it. You could use MvcContrib.TestHelpers for simpler unit testing your controllers.
Upvotes: 2
Reputation: 12538
When you are running your unit test, the view is not rendered. The @Html.Action("SubAction")
is only executed when the view is rendered. When you say : "I want to test some controller actions whose views contain Html.Action with PartialViews", you are actually saying that you want to test the views and logic inside views.
The reason your break in SubAction is not reached is because the MyAction view is not rendered at all. The way to go about testing these kinds of scenarios is :
View("some other non-convetional view")
then result.ViewName
will be = "some other non-convetional view"
You don't test the view name for those using convention defaults because you trust the framework to wire it up right.Upvotes: 3