Asp.net mvc 模拟在操作筛选器中使用的web服务

Asp.net mvc 模拟在操作筛选器中使用的web服务,asp.net-mvc,unit-testing,Asp.net Mvc,Unit Testing,我在ActionFilter中使用了一个外部解决方案web服务。动作过滤器为我的主页获取一些基本数据。我在使用动作过滤器和扩展基本控制器类之间来回切换,认为动作过滤器是最好的方法。然后我开始了单元测试(是的,是的TDD。无论如何…:D) 因此,我不能在操作筛选器中模拟(使用Moq,顺便说一句)web服务,因为我不能将我的模拟WS注入到操作筛选器中,因为操作筛选器不将对象作为参数。对吗?至少我似乎是这么想的 有什么想法吗?更好的方法?我只是想提醒用户,如果web服务不可用,他们的体验可能会受到限制

我在ActionFilter中使用了一个外部解决方案web服务。动作过滤器为我的主页获取一些基本数据。我在使用动作过滤器和扩展基本控制器类之间来回切换,认为动作过滤器是最好的方法。然后我开始了单元测试(是的,是的TDD。无论如何…:D)

因此,我不能在操作筛选器中模拟(使用Moq,顺便说一句)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.";
            }
        }
    }
}

这里有一个快速而肮脏的方法:

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

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

当然,这种方法并不像评论部分中的那样干净,但它在某些情况下可以工作。

如果覆盖ControllerActionInvoker,则可以将DI与ActionFilters一起使用。老实说,如果你把所有的重担都放在web服务上,那么就没有什么理由对你的动作过滤器进行单元测试。您还可以避免模仿HttpContext说得好。我只是想在web服务不可用的情况下测试优雅的降级。谢谢Darin-我最终重新评估了是否需要测试该功能:)顺便问一下,“=()=>新”语法是什么,我以前从未见过它?
objectToTest.ServiceProvider = () => new SomeMockedObject();