模拟动作过滤器中使用的Web服务

时间:2010-09-10 18:42:45

标签: asp.net-mvc unit-testing

我有一个外部到我解决方案的Web服务,我在ActionFilter中使用它。动作过滤器为我的MasterPage抓取一些基本数据。我在使用动作过滤器和扩展基本控制器类之间来回走动,并决定动作过滤器是最好的方法。然后我开始进行单元测试(是的,是的TDD。无论如何......:D)

所以我不能在动作过滤器中模拟(使用Moq,btw)Web服务,因为我无法将模拟WS注入动作过滤器,因为动作过滤器不会将对象作为参数。对?至少那是我似乎已经到来的。

有什么想法吗?更好的方法?我只是想向用户发出警告,如果Web服务不可用,他们的体验可能会受到限制。

感谢您的帮助!

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 个答案:

答案 0 :(得分:1)

这是一种快速而肮脏的方法:

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

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

在单元测试中,您可以实例化动作过滤器,并将ServiceProvider公共字段替换为一些模拟对象:

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

当然,这种方法并不像评论部分中的one suggested by @Ryan一样干净,但在某些情况下可能会有效。