使用MvcRouteTester测试Web API路由

时间:2014-12-22 04:29:34

标签: asp.net-web-api

我正在使用Anthony Steele's MVC Route Tester的MVC 4版本,这似乎是测试MVC路由的最佳产品。

我正在尝试使用以下Web API测试,但它没有发生。有人可以帮助我:

var config = new HttpConfiguration();

config.Routes.MapHttpRoute(
    name: "Testing",
    routeTemplate: "WebServices/Test.aspx",
    defaults: new
    {
        controller = "Test" // This maps to an ApiController called TestController
    }
);

config
    .ShouldMap("/WebServices/Test.aspx")
    .To<TestController>(HttpMethod.Get, x => x.Get());

此测试失败并显示错误 MvcRouteTester.Assertions.AssertionException:找不到url的控制器路由http:// site.com/WebServices/Test.aspx

当我实际运行网站时,路由工作,而不是在我的测试项目中。可能有什么不对?

1 个答案:

答案 0 :(得分:1)

我在挖掘代码后发现了这个问题。在堆栈深处,有一个从我网站的程序集中获取'可导出类型'的调用。在生产中,调用成功,但由于我的单元测试项目缺少几个程序集引用,因此对Assembly.GetExportableTypes()的调用会引发异常。此异常被捕获并丢弃,因此很难调试我之后获得“未找到控制器”异常的原因。

可以通过确保添加了所有必需的程序集来解决问题。但是,如果您想让自己的生活更轻松,您实际上可以替换抑制异常的IHttpControllerTypeResolver服务。以下是IHttpControllerTypeResolver的重新实现示例。

public class HttpControllerTypeResolverThatDoesNotIgnoreExceptionGettingLoadableTypes : DefaultHttpControllerTypeResolver
{
    public override ICollection<Type> GetControllerTypes(IAssembliesResolver assembliesResolver)
    {
        if (assembliesResolver == null)
        {
            throw new Exception();
        }

        var result = new List<Type>();

        // Go through all assemblies referenced by the application and search for types matching a predicate
        ICollection<Assembly> assemblies = assembliesResolver.GetAssemblies();
        foreach (Assembly assembly in assemblies)
        {
            Type[] exportedTypes = null;
            if (assembly == null || assembly.IsDynamic)
            {
                // can't call GetExportedTypes on a dynamic assembly
                continue;
            }

            try
            {
                exportedTypes = assembly.GetExportedTypes();
            }
            catch (ReflectionTypeLoadException ex)
            {
                exportedTypes = ex.Types;
                Trace.TraceError(ex.ToString());
            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.ToString());
                continue;
            }

            if (exportedTypes != null)
            {
                result.AddRange(exportedTypes.Where(IsControllerType));
            }
        }

        return result;
    }

    private static bool IsControllerType(Type t)
    {
        return
            t != null &&
            t.IsClass &&
            t.IsPublic &&
            t.Name.EndsWith(DefaultHttpControllerSelector.ControllerSuffix, StringComparison.OrdinalIgnoreCase) &&
            !t.IsAbstract &&
            typeof(IHttpController).IsAssignableFrom(t);
    }
}

您可以将此服务连接到您的配置,如下所示:

_yourHttpConfig.Services.Replace(typeof(IHttpControllerTypeResolver), new HttpControllerTypeResolverThatDoesNotIgnoreExceptionGettingLoadableTypes());

上述实现将输出跟踪发生的任何异常,这可能有助于调试。或者,您可以使用this one之类的方法来跳过任何无法成功加载但仍能获得其他成功可导出类型的单个可导出类型。