views:

33

answers:

1

I have an external-to-my-solution web service that I'm using in an ActionFilter. The action filter grabs some basic data for my MasterPage. I've gone back and forth between using an action filter and extending the base controller class, and decided the action filter was the best approach. Then I started unit testing (Yeah, yeah TDD. Anyway... :D )

So I can't mock (using Moq, btw) a web service in an action filter because I can't inject my mock WS into the action filter, since action filters don't take objects as params. Right? At least that's what I seem to have come to.

Any ideas? Better approaches? I'm just trying to return a warning to the user that if the web service is unavailable, their experience might be limited.

Thanks for any help!

namespace MyProject.ActionFilters
{
    public class GetMasterPageData : ActionFilterAttribute
    {
        public ThatWS ws = new ThatWS();

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            HttpContextBase context = filterContext.HttpContext;

            try {
                DoStuff();
            }
            catch ( NullReferenceException e ) {
                context.Session["message"] = "There is a problem with the web service.  Some functionality will be limited.";
            }
        }
    }
}
+1  A: 

Here's a quick and dirty approach:

public class GetMasterPageData : ActionFilterAttribute
{
    public Func<ISomeInterface> ServiceProvider = () => new ThatWS();

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var result = ServiceProvider().SomeMethod();
        ...
    }
}

And in your unit test you could instantiate the action filter and replace the ServiceProvider public field with some mocked object:

objectToTest.ServiceProvider = () => new SomeMockedObject();

Of course this approach is not as clean as the one suggested by @Ryan in the comments section but it could work in some situations.

Darin Dimitrov
Thanks Darin - I ended up reevaluating whether I needed to test that functionality or not :) Incidentally, what is the " = () => new" syntax, I've never seen it before?
morganpdx