I did a search on SO and looks like this question gets asked quite often. I have been able to get the mocks working and I'm also able to execute OnActionExecuted() without any issues. Here's my Unit Test. The commented lines are the ones that fail and I'm sure I'm not mocking the right type.
//Arrange
//var viewResult = new ViewResult();
var filterContextMock = new Mock<ActionExecutedContext>();
var routeData = new RouteData();
var httpContextMock = new Mock<HttpContextBase>();
routeData.Values["data"] = "Mock data";
var requestContext = new RequestContext(httpContextMock.Object, routeData);
var controller = new FakeController();
controller.ControllerContext = new ControllerContext(requestContext, controller);
filterContextMock.Setup(f => f.RouteData).Returns(routeData);
filterContextMock.Setup(f => f.Controller).Returns(controller);
//filterContextMock.Setup(f => f.Result).Returns(viewResult);
//Act
var wrapFilterAttribute = new WrapFilterAttribute();
wrapFilterAttribute.OnActionExecuted(filterContextMock.Object);
Here is my Action Filter.
public class WrapFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
var view = (ViewResultBase)filterContext.Result;
if (view != null)
{
BaseViewModel viewModel = (BaseViewModel)view.ViewData.Model ?? new BaseViewModel();
viewModel.Wrap = new WrapperFactory().GetWrap();
}
base.OnActionExecuted(filterContext);
}
}
The issue I'm facing here is filterContext.Result always comes in as EmptyResult. I'd like to push in a hydrated ViewResult instead. Any ideas how I can accomplish this?
Many thanks!
First let's start by fixing your action filter as currently the code looks bad and those castings might bring you headaches:
public class WrapFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
var view = filterContext.Result as ViewResultBase;
if (view != null)
{
// the controller action returned a ViewResultBase
var viewModel = view.ViewData.Model as BaseViewModel;
if (viewModel != null)
{
// the model passed to the view was derived from
// BaseViewModel so we can safely update the Wrap
// property
viewModel.Wrap = new WrapperFactory().GetWrap();
}
}
base.OnActionExecuted(filterContext);
}
}
And the unit test:
// arrange
var sut = new WrapFilterAttribute();
var filterContextMock = new Mock<ActionExecutedContext>();
var viewResultMock = new Mock<ViewResultBase>();
filterContextMock.Object.Result = viewResultMock.Object;
var viewModel = new BaseViewModel();
viewResultMock.Object.ViewData.Model = viewModel;
// act
sut.OnActionExecuted(filterContextMock.Object);
// assert
// TODO: assert something on the viewModel.Wrap property like
// for example that it has been initialized
Remark: Your action filter has a strong dependency on WrapperFactory
class. This is not good. A further improvement would be to abstract this functionality into an interface which would be injected into the constructor of the action filter. This would allow you further separation of concerns between different layers of your application.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With